Java数据结构——单链表
一、单链表的概念
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。这组存储单元可以是连续的,也可以是不连续的。
存储单元由两部分组成,数据源和指针,数据源放数据,指针指向下个存储单元。
二、单链表的结构
采用Node实体类类标识,其中data为存储的数据,next为下一个结点的指针。
//链表的实体类 class Node{ public int data; public Node next; public Node(int data) { this.data = data; } }
三、单链表的常见操作
package org.learn.link; import java.util.Stack; public class TestList { public static void main(String[] args) { // TODO Auto-generated method stub MyLinkedLsit mylist = new MyLinkedLsit(); mylist.addNodeH(22); mylist.addNodeH(32); mylist.addNodeH(25); mylist.addNodeH(11); mylist.print(); System.out.println("链表的长度:"+mylist.getLength()); System.out.println(mylist.findLastIndexNode(mylist.getHead(), 3).data); mylist.reverseList(mylist.getHead()); System.out.println("反转的链表:"); mylist.print(); System.out.println("栈逆序输出的链表:"); mylist.reversePrint(); //mylist.delete(1); //mylist.print(); } } class MyLinkedLsit{ //初始化头结点(不存放具体数据) Node head = new Node(0); //返回头结点 public Node getHead() { return head; } //添加结点(尾插法) public void addNodeT(int data) { Node newnode = new Node(data);//生成新结点 Node cur = head;//当前结点 while(cur.next != null) {//找到最后一个结点 cur = cur.next; } cur.next = newnode; } //添加结点(头插法) public void addNodeH(int data) { Node newnode = new Node(data);//生成新结点 newnode.next = head.next; head.next = newnode; } //获取链表的长度 public int getLength() { int length = 0; Node cur = head.next; while(cur != null) { length++; cur = cur.next; } return length; } //删除第k个结点 public void delete(int k) { if(k<1 || k>getLength()) { System.out.println("待删除的结点不存在"); return; } int i = 1; Node cur = head; while(cur.next != null) { if(i == k) { cur.next = cur.next.next; return; } else { cur = cur.next; i++; } } } //查找链表中倒数第index个结点 public Node findLastIndexNode(Node head,int index) { //判断链表是否为空 if(head.next == null) return null; //得到结点 int size = getLength(); if(index<1 || index>size) return null; Node cur = head.next; for(int i=0;i) cur = cur.next; return cur; } //单链表反转 public void reverseList(Node head) { if(head.next == null || head.next.next == null)//如果链表为空或只有一个结点,无需反转 return; Node cur = head.next;//辅助变量,帮助遍历链表 Node nextNode = null;//指向当前结点cur的下一个结点 Node reverseNode = new Node(0);//初始化另一个头结点 //遍历原来的链表,每遍历一个结点,将其取出,并放到新的链表的最前端 while(cur!=null) { nextNode = cur.next;//暂时保存当前结点的下一个结点 cur.next = reverseNode.next;//将cur的下一个结点指向新的链表的最前端 reverseNode.next = cur;//将cur连接到新的链表 cur = nextNode;//cur后移 } head.next = reverseNode.next;//将头节点指向另一个头节点,实现单链表的反转 } //逆序打印单链表(不用反转,利用栈) public void reversePrint() { if(head.next == null) return; //Stack stack = new Stack Stack(); stack = new Stack (); Node cur= head.next; //将链表中所有结点压入栈中 while(cur!=null) { stack.push(cur.data); cur = cur.next; } //将栈中的结点进行打印 while(stack.size() >0) System.out.print(stack.pop()+" ");//栈的特点是先进后出 } //显示结点 public void print() { Node cur = head.next; while(cur != null) { System.out.print(cur.data +" "); cur = cur.next; } System.out.println(); } } //链表结点的实体类 class Node{ int data;//结点数据 Node next;//下一个结点 public Node(int data) { this.data = data; } }