单向循环链表
前面为了说明方便,有些是用的贴图,由于有些图片较大形成挤压,看不清点击看原图即可,源码会在后面给出,话不多说,开始吧!
- 节点类Node
/**
* @author AmVilCresx
* 节点类
*/
public class Node {
Object element; //数据域
Node next; // 后继指针域
Node previor;// 前驱指针域
//非头结点的构造方法
public Node(Object element) {
this.element = element;
}
}
插入链表的第一个元素
在尾部插入节点元素
- 在头部插入节点元素
在指定位置插入元素节点
删除指定位置的节点
删除给定的元素节点(注释做了简单说明,其它操作跟上面删除类似)
- 单向循环链表源码
复制粘贴开发工具,修改你自己的包名即可运行
public class Node {
Object element; //数据域
Node next; // 后继指针域
Node previor;// 前驱指针域
//非头结点的构造方法
public Node(Object element) {
this.element = element;
}
}
------------------------分割线------------------------------------
package com.avc.link;
/**
* @author AmVilCresx
* 模拟单向循环链表
* */
public class CycleLinkList{
Node head; //头指针
Node rear; //尾节点
Node currentPrior; 当前节点的前一个节点,下面的删除和插入要用
int size; //节点个数
/**
* 对空链表第一个节点进行插入
* */
private void insertFirstNode(Node node) {
head = node; //头指针指向node
rear = head; // 尾指针指向head
head.next = rear; //链接成环状
size++; //长度+1
}
/**
* 在末尾插入
* */
public void insertRear(Node node) {
if(head == null) {
insertFirstNode(node); // 插入链表的第一个元素
}else {
node.next = rear.next; //将带插入节点的next指向原链表rear的next;
rear.next = node; // 将原链表的rear的next指向node
rear = node; // 改变rear的指向 为node
size++; //长度+1
}
}
/**
* 头插法
* 头插其实就是和末尾插入一样的,只不过尾插改变的是尾指针,头指针不变,头插改变头指针,尾指针不变
* */
public void insertHead(Node node) {
if(head == null) {
insertFirstNode(node);
}else {
node.next = rear.next;
rear.next=node;
head=node; // 此处改变的是头指针head的指向
size++;
}
}
/**
* 获取节点
* */
public Node get(int index){
Node tmp = head;
int j=0;
if(index<0 || index>size-1) {
return null;
}
while(j!=index) {
tmp = tmp.next;
j++;
}
return tmp;
}
/**
* 定位到操作节点的前一个位置
* */
public void getLoation(int index) {
currentPrior = head;
int j=0;
while(j<index-1) {//找到要插入的位置前一个位置
currentPrior = currentPrior.next;
j++;
}
if(index==0) { //如果是第一个节点,则它的前一个节点就是rear节点,上面的while没处理这种情况
currentPrior=rear; //手动赋值
head=head.next; //注意:一定要将head指向下一个节点,不然get的时候会出错
}
}
/**
* 在这指定位置进行插入
* */
public void insertAnyWhere(int index,Node node) {
if(index<0 || index > size) {
throw new RuntimeException("参数非法");
}
if(index == 0) { //第一个位置,说明是头插
this.insertHead(node);
}else if(index == size) { //最后一个位置,说明是,尾插
this.insertRear(node);
}else {
getLoation(index); //定位到index的前一个位置
node.next = currentPrior.next; // 将带插入节点的next指向当前节点(也就是当前节点的前一个节点的下一个节点)
currentPrior.next=node; // 将前一个节点的next指向node,完成连接
size++; // 长度+1
}
}
/**
* 删除指定位置的节点
* */
public Node delete(int index) {
if(index<0 || index>size-1)
throw new RuntimeException("参数非法");
if(isEmpty()) {
throw new RuntimeException("链表为空,操作失败");
}
Node delNode = null;
getLoation(index); //定位到index的前一个位置
delNode = currentPrior.next; //待删除的节点(当前节点)
currentPrior.next=delNode.next; // 将当前节点的前驱节点的next指针指向当前节点的next域
size--; //长度 -1
return delNode;
}
/**
* 删除给定的节点,这里为了测试方便,默认值相同则是相同的节点,并且不存在element相同的节点
* */
public Node deleteByNode(Node node) {
Node delNode= null;
if(isEmpty()) {
throw new RuntimeException("链表为空,操作失败");
}
if(size==1 && node.element == head.element) {
delete(0);
head=null;
return node;
}
Node tmp = head; //临时指针变量
int count=size;
while(count>0 && node.element!= tmp.next.element) {
// 如果小于count,没走完一圈 或者下个节点的值不等于给定节点的值
count--;
tmp = tmp.next;
}
if(count==0) {
throw new RuntimeException("元素不存在,无法删除");
}else {
delNode = tmp.next;
if(delNode==head) { // 判断一下,不然get会出错
head=delNode.next;
}
if(tmp.next==rear) {
rear=tmp;
}
tmp.next=delNode.next; // 改变指针指向
size--;
}
return delNode;
}
//链表大小
public int size() {
return this.size;
}
/**
* 判断链表是否为空
* */
public boolean isEmpty() {
return size==0;
}
public static void main(String[] args) {
CycleLinkList list = new CycleLinkList();
/*list.insertRear(new Node(1));
list.insertRear(new Node(2));
list.insertRear(new Node(3));
System.out.println(list.get(1).getElement());*/
list.insertHead(new Node(1));
list.insertHead(new Node(2));
list.insertHead(new Node(3));
list.insertHead(new Node(4));
Node ist = new Node(6);
list.insertRear(ist);
// list.insertAnyWhere(1, new Node("insrt"));
/*System.out.println(list.get(1).element);
System.out.println("size----"+list.size());
list.delete(1);
System.out.println("size----"+list.size());
System.out.println(list.get(1).element);
System.out.println(list.get(1).next.element);*/
System.out.println("size----"+list.size());
System.out.println(list.get(3).element);
System.out.println(list.deleteByNode(ist).element);
System.out.println("size----"+list.size());
System.out.println(list.get(3).element);
}
}
双向循环链表
在尾部插入节点元素
在头部插入元素节点
在指定的位置插入节点
删除指定位置的节点元素
删除给定的节点元素
- 双向循环链表源码
package com.avc.link;
/**
* @author AmVilCresx
* 模拟双向循环链表
*
*/
public class CycleBothWayLinkList {
Node head; //头指针
Node rear; //尾节点
Node current; //当前节点,下面的删除和插入要用
int size=0; //节点个数
/**
* 插入整个链表的第一个节点
* */
private void insertFirstNode(Node node ) {
head=node;
rear=head;
head.next=rear;
head.previor=rear;// 形成双向环状
size++;
}
/**
* 尾插法
* */
public void insertRear(Node node) {
if(head == null) {
insertFirstNode(node);
}else {
node.next=rear.next; // 将带插入节点node的next指向rear的next
node.previor=rear; // 将node的前驱指向rear
rear.next.previor=node; //将rear的next的前驱指向node
rear.next=node; //将rear的next指向node
rear=node; //将rear设置为node
size++;
}
}
/**
* 头插法
* */
public void insertHead(Node node) {
if(head == null) {
insertFirstNode(node);
}else {
node.next=rear.next; // 将带插入节点node的next指向rear的next
node.previor=rear; //将node的前驱指向rear
rear.next.previor=node; //将原来rear的next节点的前驱设置为node
rear.next=node; //则rear的next指向node
head = node; // 改变head的指向
size++;
}
}
/**
* 在任意位置插入
* */
public void insertAnyWhere(int index, Node node) {
if(index<0 || index>size) {
throw new RuntimeException("参数非法!");
}
if(index ==0) {
insertHead(node);
}else if(index==size) {
insertRear(node);
}else {
getLoation(index); // 因为是双向链表,所以直接定位到要操作的节点
node.next = current; //将待插入节点的next指向当期节点
node.previor=current.previor; //将node的前驱节点设置为当前节点的前驱节点
current.previor.next=node; // 再讲当前节点的前驱的next指向node
current.previor=node; // 再将当前节点的前驱节点设置为node
size++;
}
}
/**
* 删除指定位置的节点
* */
public Node deleteNode(int index) {
if(index<0 || index>size-1)
throw new RuntimeException("参数非法");
if(isEmpty()) {
throw new RuntimeException("链表为空,操作失败");
}
getLoation(index);//找到要插入的位置的当前节点(这里也可以找要操作的节点的前一个节点,因为这里有前驱指针,可不必)
Node delNode = current;
current.previor.next=current.next;
current.next.previor=current.previor;
size--;
return delNode;
}
/**
* 删除给定的节点,这里为了测试方便,默认值相同则是相同的节点,并且不存在element相同的节点
* */
public Node deleteByGiveNode(Node node) {
Node delNode= null;
if(isEmpty()) {
throw new RuntimeException("链表为空,操作失败");
}
if(size==1 && node.element == head.element) {
deleteNode(0);
head=null;
return node;
}
Node tmp = head;
int count=size;
while(count>0 && tmp.element != node.element) {
count--;
tmp=tmp.next;
}
if(count==0) {
throw new RuntimeException("元素不存在,无法删除");
}else {
delNode = tmp;
if(delNode==head) {
head=delNode.next;
}
if(delNode==rear) {
rear=delNode.previor;
}
tmp.previor.next=tmp.next;
tmp.next.previor=tmp.previor;
size--;
}
return delNode;
}
//定位到指定位置
public void getLoation(int index) {
current = head;
int j=0;
while(j<index) {//找到要插入的位置前一个位置
current = current.next;
j++;
}
if(index ==0) {
head = current.next; //改变head的指向
}
}
/**
* 获取节点
* */
public Node get(int index){
Node tmp = head;
int j=0;
if(index<0 || index>size-1) {
return null;
}
while(j!=index) {
tmp = tmp.next;
j++;
}
return tmp;
}
public boolean isEmpty() {
return size==0;
}
//链表大小
public int size() {
return this.size;
}
/**
* main函数测试
* */
public static void main(String[] args) {
CycleBothWayLinkList cyl = new CycleBothWayLinkList();
cyl.insertHead(new Node(1));
cyl.insertHead(new Node(2));
cyl.insertHead(new Node(3));
cyl.insertHead(new Node(4));
System.out.println("前驱:"+cyl.get(0).previor.element);
System.out.println("自身:"+cyl.get(0).element);
System.out.println("后继:"+cyl.get(0).next.element);
System.out.println("---------------");
cyl.insertAnyWhere(0, new Node("insrt"));
System.out.println("前驱:"+cyl.get(0).previor.element);
System.out.println("自身:"+cyl.get(0).element);
System.out.println("后继:"+cyl.get(0).next.element);
System.out.println("---------------");
cyl.deleteNode(0);
System.out.println("前驱:"+cyl.get(0).previor.element);
System.out.println("自身:"+cyl.get(0).element);
System.out.println("后继:"+cyl.get(0).next.element);
}
}
有问题请大家留言,批评指正!共勉!!!