一.链表
二.代码展示
三.总结
一.链表
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
创建链表前须知:
首节点:存放第一个有效数据的节点
头节点:在单链表的第一个结点之前附设一个结点,它没有直接前驱,称之为头结点,头结点的数据域可以不存储任何信息,指针域指向第一个节点(首节点)的地址。头结点的作用是使所有链表(包括空表)的头指针非空
头指针:指向头节点的指针
尾节点:存放最后一个有效数据的节点
尾指针:指向尾节点的指针
建立一个单向链表
链表存储的节点
class Node {
/*
the data
*/
int data;
/*
refer to the next node
*/ Node next;
/*
the constructor
@param paraValue
*/
public Node(int paraValue) {
data = paraValue;
next = null;
}//of the constructor
}//of class Node
/*
the node head. the data is never used.
*/
Node head;
public LinkedList() {
head = new Node(0);
//head.next = null;
}//of the first constructor
next存放着下一个结点的地址,而得到这个地址后可以通过点号直接访问到下个结点的相关数据。
而链表就是这样 “ 一环扣一环 ”不断延展下去,直到出现某个引用的地址指向null,说明链表的结束。
链表中数据插入
/*
insert a value to a given position
@param paramValue the given value
@param paramPosition the given position
@return success or not.
*/
public boolean insert(int paramValue, int paramPosition) {
Node tempNode=head;
Node tempNewNode;
for(int i=0;i<paramPosition;i++)
{
if(tempNode.next==null)
{
System.out.println("The position "+paramPosition+" is illeagl");
return false;
}//of if
tempNode=tempNode.next;
}//of for i
// given the data to node tempNewNode
tempNewNode=new Node(paramValue);
tempNewNode.next=tempNode.next;
tempNode.next=tempNewNode;
return true;
}
首先需要知道插入数据的位置在哪,使用一个虚拟头结点tempNode指向head,并且在循环中不断的令
tempNode=tempNode.next;,这样就找到了目标结点的前一个结点。
步骤1.创建一个新结点 并进行不赋值 将其next指针指向目标结点的next
2.目标结点的前一个结点的next指向新结点。
注意这两步骤顺序不能调换,否则会造成链表无法正常连接。
链表数据删除
/*
delete a value at a position
@param paramPositio the given position
@return success or not.
*/
public boolean delete(int paramPosition) {
if (head.next == null) {
return false;
}//of if
Node tempNode = head;
for (int i = 0; i < paramPosition; i++) {
if (tempNode.next == null) {
System.out.println("The position " + paramPosition + " is illegal");
}//of if
tempNode = tempNode.next;
}//of for i
tempNode.next = tempNode.next.next;
return true;
}//of delete
/*
首先仍然需要找到目标结点的前一个结点,跟插入寻找类似。
我们需要删除的结点是存储DATA2的结点,
步骤 将目标结点的前驱结点的next指向我们的目标结点的下一个结点
链表按值查询
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;
}//of method locate
本过程采用tempPosition作为索引,使用tempNode结点在for循环中赋值为 temp
Node = tempNode.next,同时使用tempCurrentPosition作为计数器,一旦遇到tempNode.data == paraValue,跳出for循环。
先设置默认下标值tempPosition为-1,之所以设置一个默认非法值是因为在空表情况下,while()循环不会执行,便于直接跳过while直接返回时返回非法值告诫查无此数之作用。
二.代码展示
package dataStructure.list;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
/**
* @author Donghao Xu
*/
public class LinkedList {
/*
inner class
*/
class Node {
/*
the data
*/
int data;
/*
refer to the next node
*/ Node next;
/*
the constructor
@param paraValue
*/
public Node(int paraValue) {
data = paraValue;
next = null;
}//of the constructor
}//of class Node
/*
constructor an empty linked list.
*/
Node head;
public LinkedList() {
head = new Node(0);
//head.next = null;
}//of the first constructor
//override the method "toString"
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;
}//of toString
//reset to empty
public void reset() {
head.next = null;
}//of reset
/*
locate the given value
@param paraValue the given value
@return the position
*/
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;
}//of method locate
/*
insert a value to a given position
@param paramValue the given value
@param paramPosition the given position
@return success or not.
*/
public boolean insert(int paramValue, int paramPosition) {
Node tempNode=head;
Node tempNewNode;
for(int i=0;i<paramPosition;i++)
{
if(tempNode.next==null)
{
System.out.println("The position "+paramPosition+" is illeagl");
return false;
}//of if
tempNode=tempNode.next;
}//of for i
// given the data to node tempNewNode
tempNewNode=new Node(paramValue);
tempNewNode.next=tempNode.next;
tempNode.next=tempNewNode;
return true;
}
/*
delete a value at a position
@param paramPositio the given position
@return success or not.
*/
public boolean delete(int paramPosition) {
if (head.next == null) {
return false;
}//of if
Node tempNode = head;
for (int i = 0; i < paramPosition; i++) {
if (tempNode.next == null) {
System.out.println("The position " + paramPosition + " is illegal");
}//of if
tempNode = tempNode.next;
}//of for i
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(i, 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());
}
}
}
运行结果
Initialized, the list is: empty
Inserted, the list is: 0,1,2,3,4,
The position 100 is illeagl
Deleted, the list is: 0,1,2,3,4,
Deleted, the list is: 1,2,3,4,
Looped delete, the list is: 2,3,4,
Looped delete, the list is: 3,4,
Looped delete, the list is: 4,
Looped delete, the list is: empty
Looped delete, the list is: empty
三.总结
最初学习链表的时候,对删除,插入的指针修改很是头疼,指针究竟是指向哪个结点。链表中单向链表是最简单的一种,双向链表还会加上front指针,进行操作的时候需要修改四个指针。进行模拟的时候,画图是一种很好的解释操作的方法。使用C语言在删除结点的时候,需要手动的**free()**结点,在Java中有 垃圾回收机制.
第二周的Java代码学习也完成了。对部分注释的写法也比较熟悉,再次用Java来实现数据结构的操作,也有了更深的体会。实现访问元素的操作,适合用顺序表;实现元素的插入,删除,和移动,适合用链表,因为只需要改变相应结点的指针指向即可。
综上所述,不同类型的场景,应选择合适的存储结构会使解决问题效率提高。