这是java的自学,如有问题,欢迎指正。
目录
前言
一、Day11: 顺序表(一)
二、day12:顺序表的基本操作
1.查找
2.插入
3.删除
4.代码总览
三、day13:单链表
1.节点类的定义
2.单链表的清空
3.单链表的查找
4.单链表的插入
5.单链表的删除
总结
前言
在这周我们将要开始进行基本的线性结构的学习,难度也是相较于之前的基本语法有了一定的提升,用老师的话讲就是变得越来越有趣了。
一、Day11: 顺序表(一)
顺序表是采用顺序存储结构的线性表,顺序表的基本形式如下:
图a表示的是顺序表的基本形式,数据元素本身连续存储,每个元素所占的存储单元大小固定相同,元素的下标是其逻辑地址,而元素存储的物理地址(实际内存地址)可以通过存储区的起始地址Loc (e0)加上逻辑地址(第i个元素)与存储单元大小(c)的乘积计算而得,即:
Loc(ei) = Loc(e0) + c*i
顺序表的属性
/*
* The maximal length of the list.It is a constant value.
*/
public static final int MAX_LENGTH=10;
/*
* The actual length not exceeding MAX_LENGTH.
*/
int length;
/*
*The data stored in an array.
*/
int[] data;
我们在一开始就对顺序表的长度进行了限定,使用了final int这个关键字,在后期我们就无法对长度进行修改了
代码的总览:
package day_11;
/**
*
*This is the eleventh code.
*
* @author Juncai Chen 3039808589@qq.com.
*/
public class SequentialList {
/*
* The maximal length of the list.It is a constant value.
*/
public static final int MAX_LENGTH=10;
/*
* The actual length not exceeding MAX_LENGTH.
*/
int length;
/*
*The data stored in an array.
*/
int[] data;
/**
**************
* Construct an empty SequentialList.
**************
*/
public SequentialList() {
length=0;
data=new int[MAX_LENGTH];
}//of the first constructor
/**
**************
* Construct a sequential list using an array.
* @param paraArray The given array.Its length should not exceed the MAX_LENGTH.
**************
*/
public SequentialList(int[] paraArray) {
length=paraArray.length;
data=new int[MAX_LENGTH];
//Copy data
for (int i = 0; i < paraArray.length; i++) {
data[i]=paraArray[i];
}//of for i
}//0f the second constructor
/**
* Overrides the method claimed in Object, the superclass of any class.
*/
public String toString() {
String resultString="";
if(length==0) {
return "empty";
}//of if
for (int i = 0; i < length-1; i++) {
resultString+=data[i] + ", ";
}//of for i
resultString+=data[length-1];
return resultString;
}//of toString
/**
*
****************
*Reset to empty
*
****************
*/
public void reset() {
length=0;
}//of reset
/**
*
****************
*The entrance of the program.
*
* @param args Not used now.
****************
*/
public static void main(String[] args) {
int[] tempArray= {1,4,6,9};
SequentialList tempFirstList=new SequentialList(tempArray);
System.out.println("Initialized the first list is: "+tempFirstList.toString());
System.out.println("Again, the list is: " + tempFirstList);
tempFirstList.reset();
System.out.println("After reset, the list is: " + tempFirstList);
}//of main
}//of class
代码运行的结果:
这里的输出是我们重写了Object(所有类的父类)中的toString方法,在我们重写后的toString能够让我们的数据更加的具有可读性。
二、day12:顺序表的基本操作
1.查找
代码如下(示例):
/**
*********************
* Find the index of the given value. If it appears in multiple positions,
* simply return the first one.
*
* @param paraValue The given value.
* @return The position. -1 for not found.
*********************
*/
public int indexOf(int paraValue) {
int tempPosition = -1;
for (int i = 0; i < length; i++) {
if (data[i] == paraValue) {
tempPosition = i;
break;
} // Of if
} // Of for i
return tempPosition;
}// Of indexOf
我们将要查找的值在顺序表中第一次的位置进行记录并返回,如果在我们创建的顺序表中没有要查找的数据,我们就返回-1。需要注意的是在我们的顺序表是以数组为载体的,我们的序号是从0开始的而不是从1开始的。
2.插入
顺序表中插入元素有3种情况:
- 插入到顺序表的表头;
- 在表的中间位置插入元素;
- 在表的末尾插入元素,作为顺序表中的最后一个元素;
虽然数据元素插入顺序表中的位置有所不同,但是都使用的是同一种方式去解决,即:通过遍历,找到数据元素要插入的位置,然后做如下两步工作:
- 将要插入位置元素以及后续的元素整体向后移动一个位置;
- 将元素放到腾出来的位置上;
示意如下:
例如,在 {1,2,3,4,5}
的第 3 个位置上插入元素 6,实现过程如下:
1.遍历至顺序表存储第 3 个数据元素的位置,如图所示:
2.将元素 3 以及后续元素 4 和 5 整体向后移动一个位置,如图所示:
3.将新元素 6 放入腾出的位置,如图所示:
代码如下(示例):
/**
*********************
* Insert a value to a position. If the list is already full, do nothing.
*
* @param paraPosition The given position.
* @param paraValue The given value.
* @return Success or not.
*********************
*/
public boolean insert(int paraPosition, int paraValue) {
if (length == MAX_LENGTH) {
System.out.println("List full.");
return false;
} // Of if
if ((paraPosition < 0) || (paraPosition > length)) {
System.out.println("The position " + paraPosition + " is out of bounds.");
return false;
} // Of if
// From tail to head. The last one is moved to a new position. Because length <
// MAX_LENGTH, no exceeding occurs.
for (int i = length; i > paraPosition; i--) {
data[i] = data[i - 1];
} // Of for i
data[paraPosition] = paraValue;
length++;
return true;
}// Of insert
3.删除
从顺序表中删除指定元素,实现起来非常简单,只需找到目标元素,并将其后续所有元素整体前移 1 个位置即可。
例如,从 {1,2,3,4,5}
中删除元素 3 的过程如图所示:
代码如下(示例):
/**
*********************
* Delete a value at a position.
*
* @param paraPosition The given position.
* @return Success or not.
*********************
*/
public boolean delete(int paraPosition) {
if ((paraPosition < 0) || (paraPosition >= length)) {
System.out.println("The position " + paraPosition + " is out of bounds.");
return false;
} // Of if
// From head to tail.
for (int i = paraPosition; i < length - 1; i++) {
data[i] = data[i + 1];
} // Of for i
length--;
return true;
}// Of delete
4.代码总览
package day_12;
/**
*
* This is the eleventh code.
*
* @author Juncai Chen 3039808589@qq.com.
*/
public class SequentialList {
/*
* The maximal length of the list.It is a constant value.
*/
public static final int MAX_LENGTH = 10;
/*
* The actual length not exceeding MAX_LENGTH.
*/
int length;
/*
* The data stored in an array.
*/
int[] data;
/**
**************
* Construct an empty SequentialList.
**************
*/
public SequentialList() {
length = 0;
data = new int[MAX_LENGTH];
}// of the first constructor
/**
**************
* Construct a sequential list using an array.
*
* @param paraArray The given array.Its length should not exceed the MAX_LENGTH.
**************
*/
public SequentialList(int[] paraArray) {
length = paraArray.length;
data = new int[MAX_LENGTH];
// Copy data
for (int i = 0; i < paraArray.length; i++) {
data[i] = paraArray[i];
} // of for i
}// 0f the second constructor
/**
* Overrides the method claimed in Object, the superclass of any class.
*/
public String toString() {
String resultString = "";
if (length == 0) {
return "empty";
} // of if
for (int i = 0; i < length - 1; i++) {
resultString += data[i] + ", ";
} // of for i
resultString += data[length - 1];
return resultString;
}// of toString
/**
*
****************
* Reset to empty
*
****************
*/
public void reset() {
length = 0;
}// of reset
/**
*********************
* Find the index of the given value. If it appears in multiple positions,
* simply return the first one.
*
* @param paraValue The given value.
* @return The position. -1 for not found.
*********************
*/
public int indexOf(int paraValue) {
int tempPosition = -1;
for (int i = 0; i < length; i++) {
if (data[i] == paraValue) {
tempPosition = i;
break;
} // Of if
} // Of for i
return tempPosition;
}// Of indexOf
/**
*********************
* Insert a value to a position. If the list is already full, do nothing.
*
* @param paraPosition The given position.
* @param paraValue The given value.
* @return Success or not.
*********************
*/
public boolean insert(int paraPosition, int paraValue) {
if (length == MAX_LENGTH) {
System.out.println("List full.");
return false;
} // Of if
if ((paraPosition < 0) || (paraPosition > length)) {
System.out.println("The position " + paraPosition + " is out of bounds.");
return false;
} // Of if
// From tail to head. The last one is moved to a new position. Because length <
// MAX_LENGTH, no exceeding occurs.
for (int i = length; i > paraPosition; i--) {
data[i] = data[i - 1];
} // Of for i
data[paraPosition] = paraValue;
length++;
return true;
}// Of insert
/**
*********************
* Delete a value at a position.
*
* @param paraPosition The given position.
* @return Success or not.
*********************
*/
public boolean delete(int paraPosition) {
if ((paraPosition < 0) || (paraPosition >= length)) {
System.out.println("The position " + paraPosition + " is out of bounds.");
return false;
} // Of if
// From head to tail.
for (int i = paraPosition; i < length - 1; i++) {
data[i] = data[i + 1];
} // Of for i
length--;
return true;
}// Of delete
/**
*
****************
* The entrance of the program.
*
* @param args Not used now.
****************
*/
public static void main(String[] args) {
int[] tempArray = { 1, 4, 6, 9 };
SequentialList tempFirstList = new SequentialList(tempArray);
System.out.println("After initialization, the list is: " + tempFirstList.toString());
System.out.println("Again, the list is: " + tempFirstList);
int tempValue = 4;
int tempPosition = tempFirstList.indexOf(tempValue);
System.out.println("The position of " + tempValue + " is " + tempPosition);
tempValue = 5;
tempPosition = tempFirstList.indexOf(tempValue);
System.out.println("The position of " + tempValue + " is " + tempPosition);
tempPosition = 2;
tempValue = 5;
tempFirstList.insert(tempPosition, tempValue);
System.out.println(
"After inserting " + tempValue + " to position " + tempPosition + ", the list is: " + tempFirstList);
tempPosition = 8;
tempValue = 10;
tempFirstList.insert(tempPosition, tempValue);
System.out.println(
"After inserting " + tempValue + " to position " + tempPosition + ", the list is: " + tempFirstList);
tempPosition = 3;
tempFirstList.delete(tempPosition);
System.out.println("After deleting data at position " + tempPosition + ", the list is: " + tempFirstList);
for (int i = 0; i < 8; i++) {
tempFirstList.insert(i, i);
System.out.println("After inserting " + i + " to position " + i + ", the list is: " + tempFirstList);
} // Of for i
tempFirstList.reset();
System.out.println("After reset, the list is: " + tempFirstList);
}// of main
}// of class
运行的结果如下:
在我们的顺序表中,存取速度高效,通过下标来直接访问,对于查找操作是很方便的。
但插入和删除比较慢,在插入或者删除一个元素的时候,需要遍历整个顺序表移动前后的数据,是极其不方便的。
顺序表还需要预先分配足够大的空间,估计的过大,会导致顺序表后的大量空间被闲置;但是估计的过小,又会造成溢出。
三、day13:单链表
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
1.节点类的定义
/**
* An inner class
*/
class Node {
/**
* the data
*/
int data;
/**
* the reference to the next node
*/
Node next;
/**
* **************
* The Constructor
*
* @param paraValue the data
* **************
*/
public Node(int paraValue) {
data = paraValue;
next = null;
}// of the constructor
}// of the class Node
data就是我们的数据域,next指向了下一个结点的地址,最后一个结点的next是指向null的,单链表的示意图如下:
2.单链表的清空
/**
*
****************
* Reset to empty.
****************
*/
public void reset() {
head.next = null;
}// of reset
单链表中的清空只需要讲头结点执行null即可完成我们的清空操作
3.单链表的查找
代码如下:
/**
*********************
* Locate the given value. If it appears in multiple positions, simply return
* the first one.
*
* @param paraValue The given value.
* @return The position. -1 for not found.
*********************
*/
public int locate(int paraValue) {
int tempPosition = -1;
Node tempNode = head.next;
int tempCurrentPosition = 0;
while (tempNode != null) {
if (tempNode.data == paraValue) {
tempPosition = tempCurrentPosition;
break;
} // of if
tempNode = tempNode.next;
tempCurrentPosition++;
} // of while
return tempPosition;
}// 0f locate
先设置默认下标值tempPosition为-1,之所以设置一个默认非法值是因为在空表情况下,while()循环不会执行,便于直接跳过while直接返回时返回非法值告诫查无此数之作用。而我们把计数器仅仅放于while()内计数,等到出现tempNode.data == paraValue
后将计数器交付给tempPosition,退出while(),将由tempPosition交付结果。
4.单链表的插入
在我们插入式将新结点的指针指向目标结点,在将目标结点的前一个结点指向我们的新结点,在我们插入时必须要先执行1操作,不能调换顺序,否则会导致我们后面那些结点的数据丢失。
代码示例:
/**
*********************
* Insert a value to a position. If the list is already full, do nothing.
*
* @param paraPosition The given position.
* @param paraValue The given value.
* @return Success or not.
*********************
*/
public boolean insert(int paraPosition, int paraValue) {
Node tempNode = head;
Node tempNewNode;
for (int i = 0; i < paraPosition; i++) {
if (tempNode.next == null) {
System.out.println("The position " + paraPosition + " is illegal.");
return false;
} // of if
tempNode = tempNode.next;
} // of for i
// Construct a new node.
tempNewNode = new Node(paraValue);
// Now link them.
tempNewNode.next = tempNode.next;
tempNode.next = tempNewNode;
return true;
}// of insert
5.单链表的删除
在链表的删除中我们只需将要删除的目标结点的前一个结点指向我们的目标结点的后一个结点即可。
代码示例:
/**
*********************
* Delete a value at a position.
*
* @param paraPosition The given position.
* @return Success or not.
*********************
*/
public boolean delete(int paraPosition) {
if (head.next == null) {
System.out.println("Cannot delete element from an empty list.");
return false;
} // of if
Node tempNode = head;
for (int i = 0; i < paraPosition; i++) {
if (tempNode.next.next == null) {
System.out.println("The position " + paraPosition + " is illegal.");
return false;
} // of if
tempNode = tempNode.next;
} // of for i
// delete the Node.
tempNode.next = tempNode.next.next;
return true;
}// of delete
代码的总览:
package day_13;
/**
*
* This is the thirteenth code.
*
* @author Juncai Chen 3039808589@qq.com.
*
*/
public class LinkedList {
/**
* An inner class
*/
class Node {
/**
* the data
*/
int data;
/**
* the reference to the next node
*/
Node next;
/**
* **************
* The Constructor
*
* @param paraValue the data
* **************
*/
public Node(int paraValue) {
data = paraValue;
next = null;
}// of the constructor
}// of the class Node
/**
* The head node.the data is never used.
*/
Node head;
/**
* The Constructor for Linkedlist.
*/
public LinkedList() {
head = new Node(0);
// head.next = null
}// of the Linkedlist
/**
* ****************
* Overrides the method in Object,the superclass of any class.
* ****************
*/
public String toString() {
String resultString = "";
if (head.next == null) {
return "empty";
} // of if
Node tempNode = head.next;
while (tempNode != null) {
resultString += tempNode.data + ", ";
tempNode = tempNode.next;
} // of while
return resultString;
}
/**
*
****************
* Reset to empty.
****************
*/
public void reset() {
head.next = null;
}// of reset
/**
*********************
* Locate the given value. If it appears in multiple positions, simply return
* the first one.
*
* @param paraValue The given value.
* @return The position. -1 for not found.
*********************
*/
public int locate(int paraValue) {
int tempPosition = -1;
Node tempNode = head.next;
int tempCurrentPosition = 0;
while (tempNode != null) {
if (tempNode.data == paraValue) {
tempPosition = tempCurrentPosition;
break;
} // of if
tempNode = tempNode.next;
tempCurrentPosition++;
} // of while
return tempPosition;
}// 0f locate
/**
*********************
* Insert a value to a position. If the list is already full, do nothing.
*
* @param paraPosition The given position.
* @param paraValue The given value.
* @return Success or not.
*********************
*/
public boolean insert(int paraPosition, int paraValue) {
Node tempNode = head;
Node tempNewNode;
for (int i = 0; i < paraPosition; i++) {
if (tempNode.next == null) {
System.out.println("The position " + paraPosition + " is illegal.");
return false;
} // of if
tempNode = tempNode.next;
} // of for i
// Construct a new node.
tempNewNode = new Node(paraValue);
// Now link them.
tempNewNode.next = tempNode.next;
tempNode.next = tempNewNode;
return true;
}// of insert
/**
*********************
* Delete a value at a position.
*
* @param paraPosition The given position.
* @return Success or not.
*********************
*/
public boolean delete(int paraPosition) {
if (head.next == null) {
System.out.println("Cannot delete element from an empty list.");
return false;
} // of if
Node tempNode = head;
for (int i = 0; i < paraPosition; i++) {
if (tempNode.next.next == null) {
System.out.println("The position " + paraPosition + " is illegal.");
return false;
} // of if
tempNode = tempNode.next;
} // of for i
// delete the Node.
tempNode.next = tempNode.next.next;
return true;
}// of delete
/**
*********************
* The entrance of the program.
*
* @param args Not used now.
*********************
*/
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);
} // Of for 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());
} // of for i
}// of main
}// of class LinkedList
代码的运行结果:
在单链表中,插入和删除速度快,保留原有的物理顺序,在插入或者删除一个元素的时候,只需要改变next的指向就可以了,还不用事先就分配空间,但单链表查找时是不如顺序表的,顺序表的顺序存储使它查找十分方便。
总结
在线性数据结构中,顺序表和单链表在插入、删除和查找中各自有各自的优缺点,各自的优缺点在上面都已经提出来了,这里就不过多阐述了。通过刚开始的线性数据结构就感受到了不像之前的基础语法那么的简单,需要花费更多的时间去理解它,虽然后面的只会越来越难,但是相信也会越来越有趣的。