链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
每个数据元素单元里有date域和next指针域。next指针指向下一个数据元素的date域,这样把整个链表像像一个链一样连起来。要注意保证next域指向的元素唯一。
写了一个Node类,定义数据类型:
class Node {
int data;//data域
Node next;//next指针域
public Node(int paraValue) {
data = paraValue;
next = null;
}
}
在链表中设置一个头节点(不存储任何数据),便于对链表的统一操作(增删改查),否则还得对第一个节点专门设置操作。
Node header;//头节点
对toString方法进行重写,(具体在DAY4)
当对对象打印输出的时候,可以发现,直接输出对象与调用对象的toString()方法产生的效果是一致的。因为当输出对象的时候,调用的也是对象的toString()方法,只不过其不可见而已。
当使用toString()方法对象进行描述时,输出格式为:类名+@+哈希码。hashCode的值在JAVA中不同对象输出不同的值,hashCode是通过将对象的地址转换成一个整数来实现。
一般是方法希望获得一个对象的详细信息,可以对toSting方法进行重写。此处对其进行了重写。
//重写方法,这个在DAY3中写过
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;
}
查找操作在插入和删除操作里面都要用,在链表上的操作都是利用指针来进行。
1.查找操作
写locate方法,设置两个指针:tempPosition(遍历指针,用来向后查找)和tempCurrentPosition(指向当前的元素位置),利用while循环进行查找。找到了用tempCurrentPosition指针赋值给tempPosition,再返回。
//查找
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;//返回
}
2.插入操作
输入待插入元素和待插入元素的位置。
关键是找到待插入元素的前一个位置,将新元素插入链表。
//插入元素
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;
}
3.删除操作
本操作为按存储位置删除,先查找到待删除的元素位置。设置一个指针,用指针的元素的指针指向下下个元素的data域,完成删除。
//删除
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[]) {
linklist tempFirstList = new linklist();
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());
}
}
结果为
总结:下面比较一下顺序表和链表,在增删改查这些操作上,顺序表需要大量移动元素,而链表效率高,大大减小了时间复杂度。但是顺序表又可以随机访问。所以说,选择哪种数据结构进行存储要具体问题具体分析。