单向链表是一种线性表,实际上是由节点(Node)组成的,一个链表拥有不定数量的节点。其数据在内存中存储是不连续的,它存储的数据分散在内存中,每个结点只能也只有它能知道下一个结点的存储位置。由N各节点(Node)组成单向链表,每一个Node记录本Node的数据及下一个Node。向外暴露的只有一个头节点(Head),我们对链表的所有操作,都是直接或者间接地通过其头节点来进行的。
Java代码1
import lianbiao.MyLink.Node;
public class SingleList {
// 由于类中的静态方法不能直接调用动态方法,所以将Node内部类修饰为静态类
public static class Node{
public int data;
public Node next;
public Node(){}
public Node(int data){
this.data = data;
this.next = null;
}
public int getData() {
return this.data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return this.next;
}
public void setNext(Node next) {
this.next = next;
}
}
//对头结点的初始化,如果不初始化,将会空指针异常,无法进行以下Node temp=head; temp.next的操作
public Node head = new Node(2);
//count用来统计链表的长度
public int count;
public SingleList(){}
/**
* 统计链表中结点的个数
* @return
*/
public int size(){
return this.count;
}
/**
* 判断链表是否为空
* @return
*/
public boolean isEmpty(){
return this.head == null ? true : false;
}
/**
* 增加一个结点
* @param node
* 在链表的最后插入新的结点
* 将原本最后一个结点的next指向新结点
*/
public void addNode(Node node){
//一个移动的指针(把头结点看做一个指向结点的指针)
Node temp=head;
//遍历单链表,直到遍历到最后一个则跳出循环
while(temp.next != null){
//往后移一个结点,指向下一个结点。
temp=temp.next;
}
//temp为最后一个结点,将其next指向新结点
temp.next=node;
//统计结点的个数
count++;
}
/**
* 在指定位置插入结点
* @param index
* @param node
*/
public void insertNodeByIndex(int index,Node node){
if(index<1 || index>this.count){
System.out.println(count);
System.out.println("插入的位置不合理");
return ;
}
//记录我们遍历到第几个结点了,也就是记录位置。
int length = 1;
//可移动的指针
//我们的temp代表的是当前位置的前一个结点。
//前一个结点 当前位置 后一个结点
//temp temp.next temp.next.next
Node temp = head;
//遍历单链表
while(head.next != null){
//判断是否到达指定位置
if(index == length){
//结点插入操作
node.next = temp.next;
temp.next = node;
count++;
return;
}
length++;
temp = temp.next;
}
}
/**
* 删除某个位置的结点
* @param index
*/
public void deleteNodeByIndex(int index){
if(index<1 || index>=this.count){
System.out.println("给定的位置不合理");
return ;
}
int length=1;
Node temp = head;
while(temp.next != null){
if(index == length){
//结点删除操作
temp.next = temp.next.next;
count--;
return;
}
length++;
temp = temp.next;
}
}
/**
* 某个数据是否在链表中
* @param data
* @return
*/
public boolean isContain(int data){
//flag为函数标记,用来表示函数执行的结果
boolean flag=false;
//temp为头结点 tail为头结点的下一个结点
Node temp=head;
Node tail=head.next;
if(temp == null){
System.out.println("该链表是空链表!");
flag = false;
}
else{
while(tail != null){
if(tail.data==data){
flag = true;
break;
}
temp = tail;
tail = tail.next;
}
}
return flag;
}
public void print(){
Node temp=head.next;
System.out.print("链表遍历结果为: ");
while(temp != null){
System.out.print(temp.data+" ");
temp = temp.next;
}
System.out.println();
}
public static void main(String[] args) {
SingleList list = new SingleList();
/*SingleList.Node nodes = new Node(7)是对链表头结点的初始化操作
初始化值的大小不影响最终的函数运行结果
如果不进行初始化操作,nodes为null,无法调用链表的长度,添加结点等函数操作*/
SingleList.Node nodes = new Node(7);
System.out.println(list.isEmpty());
System.out.println("链表的长度为:"+list.size());
System.out.println("==================");
SingleList.Node nodes1 = new Node(2);
SingleList.Node nodes2 = new Node(2);
SingleList.Node nodes3 = new Node(6);
list.addNode(nodes);
list.insertNodeByIndex(1, nodes1);
list.insertNodeByIndex(5, nodes2);
System.out.println(list.isEmpty());
System.out.println("链表的长度为:"+list.size());
System.out.println("==================");
list.addNode(nodes3);
System.out.println(list.isEmpty());
System.out.println("链表的长度为:"+list.size());
System.out.println("==================");
list.deleteNodeByIndex(4);
System.out.println(list.isEmpty());
System.out.println("链表的长度为:"+list.size());
System.out.println("==================");
list.print();
System.out.println("链表中是否存在2这个元素:"+list.isContain(2));
System.out.println("链表中是否存在5这个元素:"+list.isContain(5));
System.out.println("链表中是否存在6这个元素:"+list.isContain(6));
}
}
程序运行结果:
false
链表的长度为:0
==================
2
插入的位置不合理
false
链表的长度为:2
==================
false
链表的长度为:3
==================
给定的位置不合理
false
链表的长度为:3
==================
链表遍历结果为: 2 7 6
链表中是否存在2这个元素:true
链表中是否存在5这个元素:false
链表中是否存在6这个元素:true
Java代码2
import lianbiao.SingleList.Node;
public class MyLink {
//定义链表头结点
Node head = null;
static class Node {
// 节点的引用,指向下一个节点
Node next = null;
// 节点的对象,即数据域
int data;
Node(){}
public Node(int data) {
this.data = data;
}
}
/**
* 增加一个结点
* @param d
*/
public void addNode(int d) {
// 实例化一个节点
Node newNode = new Node(d);
if (head == null) {
head = newNode;
return;
}
//一个移动的指针(把头结点看做一个指向结点的指针)
Node tmp = head;
while (tmp.next != null) {
tmp = tmp.next;
}
//temp为最后一个结点,将其next指向新结点
tmp.next = newNode;
}
public void insertNodeByIndex(int index,Node node){
if (index < 1 || index > length()) {
System.out.println("插入的位置不合理");
return ;
}
int i=1;
Node preNode = head;
Node curNode = preNode.next;
//遍历单链表
while(curNode != null){
//判断是否到达指定位置
if(i == index){
//结点插入操作
node.next = curNode;
preNode.next = node;
return;
}
preNode = curNode;
curNode = curNode.next;
i++;
}
}
/**
* @param index:删除第index个节点
* @return
*/
public boolean deleteNode(int index) {
if (index < 1 || index > length()) {
return false;
}
if (index == 1) {
head = head.next;
return true;
}
//i表示第i个位置
int i = 1;
Node preNode = head;
Node curNode = preNode.next;
//循环遍历寻找第i个结点的位置
while (curNode != null) {
if (i == index) {
preNode.next = curNode.next;
return true;
}
preNode = curNode;
curNode = curNode.next;
i++;
}
return false;
}
/**
* 链表长度
* @return 返回节点长度
*/
public int length() {
int length = 0;
Node tmp = head;
while (tmp != null) {
length++;
tmp = tmp.next;
}
return length;
}
/**
* 某个数据是否在链表中
* @param data
* @return
*/
public boolean isContain(int data){
//flag为函数标记,用来表示函数执行的结果
boolean flag=false;
//temp为头结点 tail为头结点的下一个结点
Node temp=head;
Node tail=head.next;
if(temp == null){
System.out.println("该链表是空链表!");
flag = false;
}
else{
while(tail != null){
if(tail.data==data){
flag = true;
break;
}
temp = tail;
tail = tail.next;
}
}
return flag;
}
/**
* 打印链表
*/
public void printList() {
Node tmp = head;
while (tmp != null) {
System.out.print(tmp.data+" ");
tmp = tmp.next;
}
System.out.println();
}
public static void main(String[] args) {
MyLink list = new MyLink();
System.out.println("链表的长度为:" + list.length());
System.out.println("================");
list.addNode(5);
list.addNode(3);
list.addNode(1);
list.addNode(2);
list.addNode(55);
list.addNode(36);
System.out.println("链表的长度为:" + list.length());
System.out.println("头结点的数据域为:" + list.head.data);
System.out.print("链表打印结果为:");
list.printList();
System.out.println("================");
list.deleteNode(4);
System.out.print("After deleteNode(4):");
System.out.print("链表打印结果为:");
list.printList();
System.out.println("================");
//如果不使用list.insertNodeByIndex(3, new Node(25))代码,Node内部类将不用定义为静态内部类
list.insertNodeByIndex(3, new Node(25));
System.out.println("链表的长度为:" +list.length());
System.out.print("链表打印结果为:");
list.printList();
System.out.println("================");
System.out.println("链表是否包含数据域为25的结点:"+list.isContain(25));
System.out.println("链表是否包含数据域为10的结点:"+list.isContain(10));
}
}
程序运行结果:
链表的长度为:0
================
链表的长度为:6
头结点的数据域为:5
链表打印结果为:5 3 1 2 55 36
================
After deleteNode(4):链表打印结果为:5 3 1 2 36
================
链表的长度为:6
链表打印结果为:5 3 1 25 2 36
================
链表是否包含数据域为25的结点:true
链表是否包含数据域为10的结点:false