Day 11: 顺序表(一)
顺序表:指用一组地址连续的存储单元依次存储各个元素,使得在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中的线性表
public class SequentialList {
public static final int MAX_LENGTH = 10;//顺序表的最大长度
int length;//顺序表中的成员数量
int[] data;//用来存储数据的数组
public SequentialList() {
length = 0;
data = new int[MAX_LENGTH];
}// 创建一个空的顺序表
public SequentialList(int[] paraArray) {
data = new int[MAX_LENGTH];
length = paraArray.length;//通过已有的数组去产生一个顺序表
for (int i = 0; i < paraArray.length; i++) {
data[i] = paraArray[i];
} //将形参数据复制到data里
}
public String toString() {
String resultString = "";
if (length == 0) {
return "empty";
}
for (int i = 0; i < length - 1; i++) {
resultString += data[i] + ", ";
}
resultString += data[length - 1];
return resultString;
}
public void reset() {
length = 0;
}//重置顺序表
public static void main(String args[]) {
int[] tempArray = { 1, 2, 3, 4, 5, };
SequentialList tempFirstList = new SequentialList(tempArray);
System.out.println("Initialized, the list is: " + tempFirstList.toString());
System.out.println("Again, the list is: " + tempFirstList);
tempFirstList.reset();
System.out.println("After reset, the list is: " + tempFirstList);
}
}

Day12:顺序表(二)
12.1 查找给定元素所处的位置. 找不到就返回 -1.
12.2 在给定位置增加元素. 如果线性表已满, 或位置不在已有位置范围之内, 就拒绝增加. 该位置可以是在最后一个元素之后一个.
12.3 删除定定位置的元素. 要处理给定位置不合法的情况. 该位置必须是已经有数据的.
public class SequentialList2 {
public static void main(String[] args) {
int[] tempArray = {1, 4, 6, 9 };
SequentialList2 tpFirstList = new SequentialList2(tempArray);
System.out.println("Initialized, the list is: " + tpFirstList.toString());
System.out.println("Again, the list is: " + tpFirstList);
int tempValue = 4;
int tpPosition = tpFirstList.locate(tempValue);
System.out.println("The position of " + tempValue + " is " + tpPosition);
tempValue = 5;
tpPosition = tpFirstList.locate(tempValue);
System.out.println("The position of " + tempValue + " is " + tpPosition);
tpPosition = 2;
tempValue = 5;
tpFirstList.insert(tpPosition, tempValue);
System.out.println("After inserting " + tempValue + " to position " + tpPosition
+ ", the list is: " + tpFirstList);
tpPosition = 8;
tempValue = 10;
tpFirstList.insert(tpPosition, tempValue);
System.out.println("After inserting " + tempValue + " to position " + tpPosition
+ ", the list is: " + tpFirstList);
tpPosition = 3;
tpFirstList.delete(tpPosition);
System.out.println("After deleting data at position " + tpPosition + ", the list is: "
+ tpFirstList);
for (int i = 0; i < 8; i++) {
tpFirstList.insert(i, i);
System.out.println("After inserting " + i + " to position " + i
+ ", the list is: " + tpFirstList);
}
tpFirstList.reset();
System.out.println("After reset, the list is: " + tpFirstList);
}
//顺序表的最大长度
public static final int MAX_LENGTH = 10;
//用来存储顺序表中的成员数量,当然也可以是数组里的成员数量
int length;
//数组,用来存储数据
int[] data;
/**
* @Description: 创建一个空顺序表
* @Param: []
* @return:
*/
public SequentialList2() {
length = 0;
data = new int[MAX_LENGTH];
}
/**
* @Description: 通过已有的数组去产生一个顺序表
* @Param: [paraArray]
* 该数组的长度不能超过MAX_LENGTH
* @return:
*/
public SequentialList2(int[] paraArray) {
length = paraArray.length;
data = new int[MAX_LENGTH];
//将形参数据复制到data里
for (int i = 0; i < length; i++) {
data[i] = paraArray[i];
}
}
public String toString() {
String resultString = "";
if (length == 0) {
return "empty";
}
for (int i = 0; i < length - 1; i++) {
resultString += data[i] + ", ";
}
resultString += data[length - 1];
return resultString;
}
/**
* @Description: 将顺序表置为空
* @Param: []
* @return: void
*/
public void reset() {
length = 0;
}
/**
* @Description: 定位元素下标
* @Param: [paraNum]
* @return: int
*/
public int locate(int paraNum) {
for (int i = 0; i < length; i++) {
if (data[i] == paraNum) {
return i;
}
}
return -1;
}
/**
* @Description: 在指定下标插入数值
* @Param: [paraIndex, paraNum]
* @return: boolean
*/
public boolean insert(int paraIndex, int paraNum) {
if (length == MAX_LENGTH) {
System.out.println("List full.");
return false;
} else if (paraIndex > length || paraIndex < 0) {
System.out.println("The position " + paraIndex + " is out of bounds.");
data[length++] = paraNum;
} else {
for (int i = length++; i > paraIndex; i--) {
data[i] = data[i - 1];
}
data[paraIndex] = paraNum;
}
return true;
}
/**
* @Description: 删除指定下标的元素
* @Param: [paraIndex]
* @return: boolean
*/
public boolean delete(int paraIndex) {
if (paraIndex >= length || paraIndex < 0) {
System.out.println("The position " + paraIndex + " is out of bounds.");
return false;
} else {
for (int i = paraIndex; i < length - 1; i++) {
data[i] = data[i + 1];
}
length--;
}
return true;
}
}

Day13 :链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。
每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节点含有的信息),一个是引用域(储存下一个节点或者上一个节点的地址)。

head为头节点,他不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用,而每个节点中都有一个next引用,指向下一个节点,就这样一节一节往下面记录,直到最后一个节点,其中的next指向null。
public class LinkedList {
//创建Node类
class Node {
//储存数据的变量
int data;
//存放节点的变量
Node next;
//构造方法
public Node(int paraValue) {
data = paraValue;
next = null;
}
}
//头结点,不使用其数据
Node header;
//初始化链表
public LinkedList() {
header = new Node(0);
}
public String toString() {
String resultString = "";
if (header.next == null) {
return "empty";
}
Node tempNode = header.next;
while (tempNode != null) {
resultString += tempNode.data + ", ";
tempNode = tempNode.next;
}
return resultString;
}
//重置为空,释放空间
public void reset() {
header.next = null;
}
/**
* @Description: 定位
* 未找到就返回-1
* @Param: [paraValue]
* @return: int
*/
public int locate(int paraValue) {
int tempPosition = -1;
Node tempNode = header.next;
int tempCurrentPosition = 0;
while (tempNode != null) {
if (tempNode.data == paraValue) {
tempPosition = tempCurrentPosition;
break;
}
tempNode = tempNode.next;
tempCurrentPosition++;
}
return tempPosition;
}
/**
* @Description: 插入节点
* 先判断位置是否合法,再将其插入
* @Param: [paraPosition, paraValue]
* @return: boolean
*/
public boolean insert(int paraPosition, int paraValue) {
Node tempNode = header;
Node tempNewNode;
for (int i = 0; i < paraPosition; i++) {
if (tempNode.next == null) {
System.out.println("The position " + paraPosition + " is illegal.");
return false;
}
tempNode = tempNode.next;
}
// 构建新节点
tempNewNode = new Node(paraValue);
// 连接它们
tempNewNode.next = tempNode.next;
tempNode.next = tempNewNode;
return true;
}
/**
* @Description: 删除节点
* 先判断位置是否合法,再根据当前节点进行删除
* @Param: [paraPosition]
* @return: boolean
*/
public boolean delete(int paraPosition) {
if (header.next == null) {
System.out.println("Cannot delete element from an empty list.");
return false;
}
Node tempNode = header;
for (int i = 0; i < paraPosition; i++) {
if (tempNode.next.next == null) {
System.out.println("The position " + paraPosition + " is illegal.");
return false;
}
tempNode = tempNode.next;
}
tempNode.next = tempNode.next.next;
return true;
}
public static void main(String args[]) {
LinkedList tempFirstList = new LinkedList();
System.out.println("Initialized, the list is: " + tempFirstList.toString());
for (int i = 0; i < 5; i++) {
tempFirstList.insert(0, i);
}
System.out.println("Inserted, the list is: " + tempFirstList.toString());
tempFirstList.insert(6, 9);
tempFirstList.delete(4);
tempFirstList.delete(2);
System.out.println("Deleted, the list is: " + tempFirstList.toString());
tempFirstList.delete(0);
System.out.println("Deleted, the list is: " + tempFirstList.toString());
for (int i = 0; i < 5; i++) {
tempFirstList.delete(0);
System.out.println("Looped delete, the list is: " + tempFirstList.toString());
}
}
}

Day14:栈
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
public class CharStack {
//栈的最大长度
public static final int MAX_DEPTH = 10;
//栈的当前长度
int depth;
//存储数据
char[] data;
//创建新的栈
public CharStack() {
depth = 0;
data = new char[MAX_DEPTH];
}
public String toString() {
String resultString = "";
for (int i = 0; i < depth; i++) {
resultString += data[i];
}
return resultString;
}
//入栈
public boolean push(char paraChar) {
if (depth == MAX_DEPTH) {
System.out.println("Stack full.");
return false;
}
data[depth] = paraChar;
depth++;
return true;
}
//出栈
public char pop() {
if (depth == 0) {
System.out.println("Nothing to pop.");
return '\0';
}
char resultChar = data[depth - 1];
depth--;
return resultChar;
}
public static void main(String args[]) {
CharStack tempStack = new CharStack();
for (char ch = 'a'; ch < 'f'; ch++) {
tempStack.push(ch);
System.out.println("The current stack is: " + tempStack);
}
char tempChar;
for (int i = 0; i < 6; i++) {
tempChar = tempStack.pop();
System.out.println("Poped: " + tempChar);
System.out.println("The current stack is: " + tempStack);
}
}
}

Day15:栈的应用(括号匹配)
任务描述: 检查一个字符串的括号是否匹配. 所谓匹配, 是指每个左括号有相应的一个右括号与之对应, 且左括号不可以出现在右括号右边. 可以修改测试字符串, 检查不同情况下的运行.
public class CharStack2 {
public static final int MAX_DEPTH = 10;
int depth;
char[] data;
//创建新的栈
public CharStack2() {
depth = 0;
data = new char[MAX_DEPTH];
}
public String toString() {
if(depth==0){
return "empty";
}
String resultString = "";
for (int i = 0; i < depth - 1; i++) {
resultString += data[i] + ", ";
}
resultString += data[depth-1];
return resultString;
}
public static boolean bracketMatching(String paraString) {
// Step 1. 创建一个栈,通过按下#来初始化栈
CharStack tempStack = new CharStack();
tempStack.push('#');
char tempChar, tempPopedChar;
// Step 2. 将各种括号依次入栈出栈比较,无法匹配则输出false
for (int i = 0; i < paraString.length(); i++) {
tempChar = paraString.charAt(i);
switch (tempChar) {
case '(':
case '[':
case '{':
tempStack.push(tempChar);
break;
case ')':
tempPopedChar = tempStack.pop();
if (tempPopedChar != '(') {
return false;
}
break;
case ']':
tempPopedChar = tempStack.pop();
if (tempPopedChar != '[') {
return false;
}
break;
case '}':
tempPopedChar = tempStack.pop();
if (tempPopedChar != '{') {
return false;
}
break;
default:
}
}
tempPopedChar = tempStack.pop();
if (tempPopedChar != '#') {
return false;
}
return true;
}
public static void main(String args[]) {
boolean tempMatch;
String tempExpression = "[2 + (1 - 3)] * 4";
tempMatch = bracketMatching(tempExpression);
System.out
.println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);
tempExpression = "( ) )";
tempMatch = bracketMatching(tempExpression);
System.out
.println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);
tempExpression = "()()(())";
tempMatch = bracketMatching(tempExpression);
System.out
.println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);
tempExpression = "({}[])";
tempMatch = bracketMatching(tempExpression);
System.out
.println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);
tempExpression = ")(";
tempMatch = bracketMatching(tempExpression);
System.out
.println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);
}
}

Day16:递归
递归:具体来讲就是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。
递归条件:
- 可以通过递归调用来缩小问题规模,且新问题与原问题有着相同的形式。(自身调用)
- 存在一种简单情境,可以使递归在简单情境下退出。(递归出口)
Fibonacci数列的数学表达式是:
F(n) = F(n-1) + F(n-2)
F(1) = 1
F(2) = 1
public class Recursion {
public static int sumToN(int paraN) {
if (paraN <= 0) {
return 0;
}
return sumToN(paraN - 1) + paraN;
}
// 斐波那契函数
public static int fibonacci(int paraN) {
if (paraN <= 0) {
//负值无效
return 0;
} if (paraN == 1) {
return 1;
}
return fibonacci(paraN - 1) + fibonacci(paraN - 2);
}
public static void main(String args[]) {
int tempValue = 5;
System.out.println("0 sum to " + tempValue + " = " + sumToN(tempValue));
tempValue = -1;
System.out.println("0 sum to " + tempValue + " = " + sumToN(tempValue));
for(int i = 0; i < 10; i ++) {
System.out.println("Fibonacci " + i + ": " + fibonacci(i));
}
}
}

Day17:链队列
队列:只允许在一段进行插入,在另一端进行删除的线性表。
链队列:使用链表实现的队列;具有队头指针和队尾指针,指示队列元素所在的位置。
链队列特性:
只能队尾插入元素、在队头删除元素;
先进先出(First In First Out)的线性表,先进入的元素出队,后进入的元素才能出队。
public class LinkedQueue {
//重写Node类,并定义头结点和尾结点,一个结点有数据域和next指针域
class Node {
int data;
Node next;
public Node(int paraValue) {
data = paraValue;
next = null;
}
}
//队头
Node header;
//对尾
Node tail;
//初始化队列的头结点,使尾指针指向头结点。
public LinkedQueue() {
header = new Node(-1);
header.next = null;
tail = header;
}
public void enqueue(int paraValue) {
Node tempNode = new Node(paraValue);
tail.next = tempNode;
tail = tempNode;
}
//入队
public int dequeue() {
if (header.next == null) {
System.out.println("No element in the queue");
return -1;
}
int resultValue = header.next.data;
header.next = header.next.next;
return resultValue;
}
//出队
public String toString() {
String resultString = "";
if (header.next == null) {
return "empty";
}
Node tempNode = header.next;
while (tempNode != null) {
resultString += tempNode.data + ", ";
tempNode = tempNode.next;
}
return resultString;
}
public static void main(String args[]) {
LinkedQueue tempQueue = new LinkedQueue();
System.out.println("Initialized, the list is: " + tempQueue.toString());
for (int i = 0; i < 5; i++) {
tempQueue.enqueue(i + 1);
} // Of for i
System.out.println("Enqueue, the queue is: " + tempQueue.toString());
tempQueue.dequeue();
System.out.println("Dequeue, the queue is: " + tempQueue.toString());
int tempValue;
for (int i = 0; i < 5; i++) {
tempValue = tempQueue.dequeue();
System.out.println(
"Looped delete " + tempValue + ", the new queue is: " + tempQueue.toString());
}
}
}

Day 18:循环队列
循环队列:将队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间,供队列循环使用。在循环队列结构中,当存储空间的最后一个位置已被使用而再要进入队运算时,只需要存储空间的第一个位置空闲,便可将元素加入到第一个位置,即将存储空间的第一个位置作为队尾。

队列存在满和空两种情况:
队列判空的条件是front=rear
队列判满的条件是front=(rear+1)%MaxSize。
public class CircleIntQueue {
//队列长度为10
public static final int TOTAL_SPACE = 10;
//数据
int[] data;
//头指针
int head;
//尾指针
int tail;
public CircleIntQueue() {
data = new int[TOTAL_SPACE];
head = 0;
tail = 0;
}
//入队
public void enqueue(int paraValue) {
if ((tail + 1) % TOTAL_SPACE == head) {
System.out.println("Queue full.");
return;
}
data[tail % TOTAL_SPACE] = paraValue;
tail++;
}
//出队
public int dequeue() {
if (head == tail) {
System.out.println("No element in the queue");
return -1;
}
int resultValue = data[head];
head++;
return resultValue;
}
public String toString() {
String resultString = "";
if (head == tail) {
return "empty";
} //队列判空
for (int i = head; i < tail; i++) {
resultString += data[i % TOTAL_SPACE] + ", ";
} //队列判满
return resultString;
}
public static void main(String args[]) {
CircleIntQueue tempQueue = new CircleIntQueue();
System.out.println("Initialized, the list is: " + tempQueue.toString());//初始队列:
for (int i = 0; i < 5; i++) {
tempQueue.enqueue(i + 1);
}
System.out.println("Enqueue, the queue is: " + tempQueue.toString());//入队,队列:
int tempValue = tempQueue.dequeue();
System.out.println("Dequeue " + tempValue + ", the queue is: " + tempQueue.toString());//出队: 队列:
for (int i = 0; i < 6; i++) {
tempQueue.enqueue(i + 10);
System.out.println("Enqueue, the queue is: " + tempQueue.toString());
}
for (int i = 0; i < 3; i++) {
tempValue = tempQueue.dequeue();
System.out.println("Dequeue " + tempValue + ", the queue is: " + tempQueue.toString());
}
for (int i = 0; i < 6; i++) {
tempQueue.enqueue(i + 100);
System.out.println("Enqueue, the queue is: " + tempQueue.toString());
}
}
}

Day19:字符串匹配
字符串是 java中特殊的类,使用方法像一般的基本数据类型,被广泛应用在 Java 编程中。在 Java 中定义一个字符串最简单的方法是用双引号把它包围起来。这种用双引号括起来的一串字符实际上都是 String 对象,如字符串“Hello”在编译后即成为 String 对象。因此也可以通过创建 String 类的实例来定义字符串。
public class MyString {
//字符串的最大长度
public static final int MAX_LENGTH = 10;
//实际长度
int length;
//存储字符
char[] data;
//构造空字符数组
public MyString() {
length = 0;
data = new char[MAX_LENGTH];
}
//字符串长度不超过 MAX_LENGTH - 1.
public MyString(String paraString) {
data = new char[MAX_LENGTH];
length = paraString.length();
//复制数据到数组
for (int i = 0; i < length; i++) {
data[i] = paraString.charAt(i);
}
}
public String toString() {
String resultString = "";
for (int i = 0; i < length; i++) {
resultString += data[i];
}
return resultString;
}
//字符串匹配
public int locate(MyString paraMyString) {
boolean tempMatch = false;
for (int i = 0; i < length - paraMyString.length + 1; i++) {
// 暴力匹配
tempMatch = true;
for (int j = 0; j < paraMyString.length; j++) {
if (data[i + j] != paraMyString.data[j]) {
tempMatch = false;
break;
}
}
if (tempMatch) {
return i;
}
}
return -1;
}
//截取出范围内的字符串
public MyString substring(int paraStartPosition, int paraLength) {
if (paraStartPosition + paraLength > length) {
System.out.println("The bound is exceeded.");
return null;
}
MyString resultMyString = new MyString();
resultMyString.length = paraLength;
for (int i = 0; i < paraLength; i++) {
resultMyString.data[i] = data[paraStartPosition + i];
}
return resultMyString;
}
public static void main(String args[]) {
MyString tempFirstString = new MyString("I like ik.");
MyString tempSecondString = new MyString("ik");
int tempPosition = tempFirstString.locate(tempSecondString);
System.out.println("The position of \"" + tempSecondString + "\" in \"" + tempFirstString
+ "\" is: " + tempPosition);
MyString tempThirdString = new MyString("ki");
tempPosition = tempFirstString.locate(tempThirdString);
System.out.println("The position of \"" + tempThirdString + "\" in \"" + tempFirstString
+ "\" is: " + tempPosition);
tempThirdString = tempFirstString.substring(1, 2);
System.out.println("The substring is: \"" + tempThirdString + "\"");
tempThirdString = tempFirstString.substring(5, 5);
System.out.println("The substring is: \"" + tempThirdString + "\"");
tempThirdString = tempFirstString.substring(5, 6);
System.out.println("The substring is: \"" + tempThirdString + "\"");
}
}

Day20:综合任务 2
1.面向对象与面向过程相比, 有哪些优势?
答:相比面向过程中处理单一的主线,面向对象能够处理更为复杂的问题;且面向对象更容易扩展和修改。
2.比较线性表和链接的异同.
答:线性表内存上是连续存储,链表是分散存储的。
3.分析线性表和链接的优缺点.
答:线性表的优点:存取速度高效,通过下标来直接存储;缺点:插入和删除比较慢,不可以增长长度;
链表的优点:插入和删除速度快,保留原有的物理顺序;缺点:查找速度慢,因为查找时,需要循环链表访问。
4.分析调拭程序常见的问题及解决方案.
答:链表存在空指针。
5.分析链队列与循环队列的优缺点.
答:链队列优点是灵活,可以随意拓展长度,缺点是入队出队都会申请内存,产生一定的时间消耗。
循环队列优点是提前申请内存,可以有效地利用资源,缺点是判断队列满时需要浪费掉一个空间。
6.第 18 天建立的两个队列, 其区别仅在于基础数据不同, 一个是 int, 一个是 char. 按这种思路, 对于不同的基础数据类型, 都需要重写一个类, 这样合理吗? 你想怎么样?
答:不合理,做个结构体,返回,里面包含各种想要返回的类型
4610




被折叠的 条评论
为什么被折叠?



