java、双向循环链表
注释比较清楚了,比较基础的实现了基本的功能
/*
* 内容:用java实现双向循环链表的增删改查
* 时间:2017.3.3
*/
package com.myList;
import java.util.Scanner;
public class MyList {
public Node head;//头结点,数据域存储链表长度
//构造函数,初始化链表
public MyList(){
this.head = null;
//head = new Node(0, null, null);
}
//创建链表
public Node createMyList(){
head = new Node(0, null, null);
System.out.println("请依次输出链表的值:");
int i = 0;
Scanner input = new Scanner(System.in);
i = input.nextInt();
Node p1 = head;
while (i != 0) {
this.head.data ++; //链表长度加1
Node p2 = new Node(i, p1, head);//新建一个结点,数据域为i,前驱p1,后继为head形成循环链表
head.prev = p2; //head头结点的前驱为最后一个结点
p1.next = p2; //p1的后继为p2
p1 = p2; //最后p1取代p2的位置,继续向下创建结点
i = input.nextInt();
}
return head;
}
//获取第i位置的结点(从1开始计数,不同于数组)
public Node getNode(int i,Node node){
Node pNode = null;
//当i的位置超出链表界限时反馈信息
if(i <= 0 || i > node.data){
System.out.println("获取失败");
} else {
pNode = node;
while(i > 0) {
pNode = pNode.next;
i --;
//System.out.println("结点数据域是:"+pNode.data);
}
}
return pNode;
}
//增:在链表node的i的位置插入一个结点,其数据域的值为x
public boolean insertMyList(Node node,int i,int x) {
boolean b = false; //返回布尔类型,用来判读操作是否成功
Node pNode = getNode(i, node);
if(pNode == null) {
System.out.println("插入失败!位置越界!");
}else {
Node pNode2 = new Node(x, pNode.prev, pNode);//插入的结点
pNode.prev.next = pNode2;
pNode.prev = pNode2;
node.data ++; //链表长度加1
b = true;
}
return b;
}
//删:删除位置为i上的结点
public boolean deleteMyList(Node node,int i) {
boolean b = false;
Node pNode = getNode(i, node);
if(pNode == null) {
System.out.println("删除失败!位置越界!");
} else {
pNode.prev.next = pNode.next;
pNode.next.prev = pNode.prev;
pNode = null;//将删除的对象置空,等待虚拟机回收内存
node.data --;//链表长度减1
b = true;
}
return b;
}
//改:修改位置为i上的结点的数据域为x
public boolean changeMyList(Node node,int i,int x) {
boolean b = false;
Node pNode = getNode(i, node);
if(pNode == null) {
System.out.println("修改失败!位置越界!");
} else {
pNode.data = x;
b= true;
}
return b;
}
//查:查询位置为i的结点的数据域
public int queryMyList(Node node,int i) {
int x = -999; //设置默认值,不宜设置为0,有可能链表有元素的值就是0
Node pNode = getNode(i, node);
if(pNode == null) {
System.out.println("查询失败!位置越界!");
} else {
x = pNode.data;
}
return x;
}
//输出链表
public void printMyList(Node node){
if(node == null || node.data == 0) {
System.out.println("链表为空!");
return ;
}
Node pNode = node.next;
System.out.println("链表长度为"+node.data);
System.out.println("输出链表为:");
while(pNode != node){
System.out.println(pNode.data);
pNode = pNode.next;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MyList myList = new MyList();
//创建链表
myList.head = myList.createMyList();
//输出链表
myList.printMyList(myList.head);
//增
/*if(myList.insertMyList(myList.head, 1, 0)) {
System.out.println("插入成功!");
myList.printMyList(myList.head);
}*/
//删
/*if(myList.deleteMyList(myList.head, 4)) {
System.out.println("删除成功!");
myList.printMyList(myList.head);
}*/
//改
/*if(myList.changeMyList(myList.head, 5, 0)) {
System.out.println("修改成功");
myList.printMyList(myList.head);
}*/
//查
if(myList.queryMyList(myList.head, 4) != -999) {
System.out.println("查询成功");
System.out.println("i位置上的数据域是"+myList.queryMyList(myList.head, 4));//i的值必须与前面的一致
//myList.printMyList(myList.head);
}
}
}
//结点类
class Node{
protected Node prev; //前驱
protected Node next; //后继
protected int data; //数据域
//构造函数
public Node(int data,Node prev,Node next){
this.data = data;
this.prev = prev;
this.next = next;
}
}
最后,有两个关于链表的小巧问题。
1、找单链表的中间结点
2、找单链表的倒数第m个结点
以上链表均不循环。。。。。循环了没意思了。