循环链表,顾名思义,链表整体要形成一个圆环状。在单向链表中,最后一个节点的指针为null,不指向任何结 点,因为没有下一个元素了。要实现循环链表,我们只需要让单向链表的最后一个节点的指针指向头结点即可。
通过实践了解循环链表
要求:设计一个测试类,使其实际运行来测试单链表类操作函数的正确性。
- 利用尾插法建立一个表长为6的单链表,从键盘输入测试数据为:12,6,5,8,10。
- 输出单链表的长度、输出单链表的各数据。
- 查找数据8所在的位置。
- 在位序号3位置插入数据元素19。
- 再次输出单链表的长度、输出单链表的各数据。
- 编写一个单链表的成员函数,实现在非递减的有序单链表中插入一个值为x的数据元素,并使单链表仍保存有序的操作,并在main函数中测试其正确性。
(例如:测试值单链表: 1,5,9,20,31 插入值x=7)进行测试
(例如:测试值单链表: 1 插入值x= -1)进行测试
public interface IList {
public void clear();
public boolean isEmpty();
public int length();
public Object get(int i) throws Exception;
public void insert(int i, Object x) throws Exception;
public int remove(int i) throws Exception;
public void dispiay();
}
package SingleLinkList;
import java.util.Scanner;
public class LinkList implements IList {
public Node head;//头指针
public LinkList() {
head=new Node();//初始化头结点
}
public LinkList(int n,boolean Order)throws Exception {
this();//初始化头结点
if (Order)
create1(n);
else
create2(n);
}
private void create2(int n) throws Exception {
//头插法
Scanner sc=new Scanner(System.in);
for (int j=0;j<n;j++)
insert(0,sc.next());
}
private void create1(int n) throws Exception {
//尾插法
Scanner sc=new Scanner(System.in);
for (int j=0;j<n;j++)
insert(length(),sc.next());
}
public void clear() {
head.next=null;
head.data=null;
}
//判断带头结点的单链表是否为空
public boolean isEmpty() {
return head.next==null;
}
//带头结点链表长度
public int length() {
Node p=head.next;
int length=0;
while (p!=null){
p=p.next;
++length;
}
return length;
}
public Object get(int i) throws Exception {
Node p=head.next;
int j=0;
while (p!=null&&j<i){
p=p.next;
++j;
}
if (j>i||p==null){
throw new Exception("第"+i+"个元素不存在");
}
return p.data;
}
//带头结点的单链表上的插入操作
public void insert(int i, Object x)throws Exception {
Node p=head;
int j=-1;
while (p!=null&&j<i-1){
p=p.next;
++j;
}
if (j>i-1||p==null)
throw new Exception("插入位置不合法");
Node s=new Node(x);
s.next=p.next;
p.next=s;
}
//删除操作
public int remove(int i) throws Exception {
Node p = head;
int j = -1;
while (p.next!= null && j < i - 1) {//寻思第i个结点的前驱
p = p.next;
++j;
}
if (j>i-1||p.next==null)
throw new Exception("删除位置不合法");
p.next=p.next.next; //修改链指针,使待删除结点从链表中脱离
return j;
}
public int indexOf(Object x) {
Node p=head.next;
int j=0;
while (p!=null&&p.data.equals(x))
p=p.next;
++j;
if (p!=null)
return j;
else
return -1;
}
//输出单链表中的所有节点
public void dispiay() {
Node node=head.next;//取出头结点
while (node!=null){
System.out.print(node.data+"\t");//输出结点的值
node=node.next;
}
}
}
public class Node {
public Object data; //存结点值
public Node next; //后继结点的引用
//无参时的构造函数
public Node() {
this(null,null);
}
//单参时的构造函数
public Node(Object data) {
this(data,null);
}
//两个参时的构造函数
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
}
public class ListTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
System.out.println("从键盘输入测试数据为:12,6,5,8,10");
LinkList L=new LinkList(5,true);//创建表长为6的单链表
System.out.println("\n创建的链表长度为:"+L.length());
System.out.printf("单链表的数据元素为:");
L.dispiay();
int getResult=L.indexOf(8);
System.out.println("\n数据为8的数据元素的位序号:"+getResult);
L.insert(3, 19);
System.out.printf("在序号3位置插入数据元素19,插入后的链表元素为:");
L.dispiay();
System.out.println("\n最终的链表长度为:"+L.length());
System.out.printf("最终的链表元素为:");
L.dispiay();
}
}
好了,同学拿去复制吧!