Java链表 之 循环单链表、双向链表

一. 循环单链表

1.如何建立一个循环单链表类

要用到内部类,整个链表是一个类,内部类为链表的Entry节点。

class TestClink{
	private Entry head = null;
	class Entry{//节点类
		int data;
		Entry next;
		public Entry(){//头结点的构造函数
			this.data = -1;
			next = null;
		}
		public Entry(int data){//带参构造函数
			this.data = data;
			next = null;
		}
	}
	
	public TestClink(){//头结点的初始化
		this.head = new Entry();
		this.head.next = this.head;//让自己指向自己
	}

2. 头插法

public void insertHead(int val){
		Entry cur1 = new Entry(val);
		cur1.next = this.head.next;//先保后面的节点
		this.head.next = cur1;
	}

3.尾插法

public void insertTail(int val){
		Entry entry = new Entry(val);
		Entry cur = this.head;
		while(cur.next != head){//遍历循环链表
			cur = cur.next;
		}
		entry.next = cur.next;
		cur.next = entry;
	}

4.删除所有值为k的节点

public void delete(int k){
		Entry cur1 = head.next;
		Entry cur2 = head;//前驱
		while(cur1 != head){
			if(cur1.data == k){
				cur2.next = cur1.next;//让前驱指向当前节点的下一个
				cur1 = cur2.next;
			}else{
				cur1 = cur1.next;
				cur2 = cur2.next;
			}
		}
	}

5.获取循环单链表的长度

public int getLength(){
		int t = 0;
		Entry cur = head.next;
		while(cur != head){
			t++;
			cur = cur.next;
		}
		return t;
	}

二. 双向链表

需要在节点域里多增加一个前驱指针prio

class TestDlink{
	private Entry head = null;
	class Entry{
		int data;
		Entry next;
		Entry prio;
		public Entry(){
			this.data = -1;
			this.next = null;
			this.prio = null;
		}
		
		public Entry(int val){
			this.data = val;
			this.next = null;
			this.prio = null;
		}
	}

双向链表的构造函数

public TestDlink(){
		this.head = new Entry();
	}

1. 头插法

public void insertHead(int val){
		Entry entry = new Entry(val);
		entry.next = this.head.next;
		entry.prio = head;
		head.next = entry;
		if(entry.next != null){
			entry.next.prio = entry;
		}
	}	
    在进行头插法时一定要注意,插入节点为链表的第一个节点的话,此时head的next域为空,不可以将entry的next的前驱指向entry,因此在写这一句
entry.next.prio = entry;

时,要加上一个条件判断,entry的next是否为空,不为空才可以将它下一个节点的prio指向entry。

3. 尾插法

public void insertTail(int val){
		Entry cur = head;
		Entry entry = new Entry(val);
		while(cur.next != null){//遍历
			cur = cur.next;
		}
		cur.next = entry;
		entry.prio = cur;
	}

4.删除双向链表的k这个元素

public void delete(int val){
		Entry cur = this.head.next;
		while(cur != null){
			if(cur.data == val){
				cur.prio.next = cur.next;
				if(cur.next != null){//只有cur的next不为空时,它的next才会有前驱
					cur.next.prio = cur.prio;
				}
				cur = cur.next;
			}else{
				cur = cur.next;
			}
		}
	}

三. 顺序栈

栈是一种先进后出的数据结构,顺序栈用数组来实现


class Stack{
	int top;//栈顶指针
	int[] elem;
	
	public Stack(){
		this(10);
	}
	public Stack(int size){
		this.elem = new int[size];
		this.top = 0;
	}
}

1. 判断栈空

public boolean isEmpty(){
		if(this.top == 0){//栈顶指针为0 
			return true;
		}
		return false;
	}
2. 判断栈满
public boolean isFull(){
		if(this.top == this.elem.length){//栈顶指针等于数组长度
			return true;
		}
		return false;
	}

3.入栈

public boolean push(int n){
		if(isFull()){//入栈之前判断栈满
			return false;
		}
		this.elem[this.top++] = n;
		return true;
	}

也可以这样写

                this.elem[this.top] = n;
		top++;

4. 出栈

public boolean pop(){
		if(isEmpty()){
			return false;
		}
		--this.top;
		return true;
	}

5.得到栈顶元素

public int getpop(){
		if(isEmpty()){//判断栈空
			return -1;
		}
		return elem[this.top - 1];
	}
不要将 this.top - 1写成 --this.top,因为函数的作用是得到栈顶元素,并非出栈。







猜你喜欢

转载自blog.csdn.net/sinat_37003267/article/details/80211054