学习数据结构创建单链表
创建单链表的两种方法:头插法,尾插法
基本运算:
- 制空表
- 判空表
- 求表长
- 查找数据值为X的元素
- 查找线性表中第i个元素
- 在线性表第I个元素之前插入数据为X的结点
- 在系欸点P之后插入一个数据值为X的结点
- 删除线性表的第I个元素
- 删除结点q的直接后继
- 显示线性表的数据元素值
直接上代码:
定义接口
package ds.linklist;
/***
* 线性表的抽象数据类型
* @author 1
*
*/
public interface IList {
public void clear(); //置空表
public boolean isEmpty();//判空表
public int length();//求表长
public Object indexOf(Object x)throws Exception;//查找数据值为x的元素
public Object get(int i)throws Exception; //查找线性表中第i个元素
public void insert(int i,Object x)throws Exception; //在线性表第i个元素之前插入数据为x的结点
public void insert(Node p,Object x)throws Exception; //在结点p之后插入一个数据值为x的结点
public void remove(int i)throws Exception; //删除线性表的第i个元素
public void remove(Node q)throws Exception; //删除结点q的直接后继
public void display(); //显示线性表的数据元素值
}
package ds.linklist;
/***
* 单链表的结点类型
* @author 1
*
*/
public class Node {
//数据域
public Object data;
//指针域
public Node next;
//构造方法
//无参数时的构造方法
public Node() {
super();
}
//带一个参数时的构造方法
public Node(Object data) {
super();
this.data = data;
}
//带两个参数时的构造方法
public Node(Object data, Node next) {
super();
this.data = data;
this.next = next;
}
}
写方法:
- 初始化一下
public class Linklist implements IList {
// 头指针
public Node head;
// 构造方法:创建头结点
public Linklist() {
head = new Node();// 初始化头结点
}
}
- 尾插法代码块
// 尾插法创建单链表
public void creatR() {
Scanner input = new Scanner(System.in);
Node s, r = head;
int i = 0;
System.out.print("请输入第" + i + "个数据元素值:");
Object x = input.next();
while (!x.equals("$")) {
s = new Node(x); // 创建新的结点
s.next = r.next; // 将结点插入到表尾
r.next = s;
r = s;
i++;
System.out.print("请输入第" + i + "个数据元素值:");
x = input.next();
}
r.next = null;
}
- 头插法代码块
// 头插法创建单链表
public void creatH() {
Scanner input = new Scanner(System.in);
Node s;
int i = 0;
System.out.print("请输入第" + i + "个数据元素值:");
Object x = input.next();
while (!x.equals("$")) {
s = new Node(x); // 创建新的结点
s.next = head.next; // 将结点插入到表头
head.next = s;
i++;
System.out.print("请输入第" + i + "个数据元素值:");
x = input.next();
}
}
- 置空表代码块
public void clear() {
head.data = null;
head.next = null;
}
- 判空表代码块
public boolean isEmpty() {
return head.next == null;
}
- 求表长代码块
public int length() {
//将p初始指向链表中第一个结点的地址
Node p=head.next;
int length=0;
while(p!=null){
p=p.next;
++length;
}
return length;
}
- 查找数据值为X的代码块
public Object indexOf(Object x) throws Exception {
Node p = head.next;
int j = 1;
while (p != null && !p.data.equals(x)) {
p = p.next; // 查找下一个结点
j++;
}
if (p == null) {
return -1;
} else
return j;
}
- 查找线性表中第 i 个元素代码块
public Object get(int i) throws Exception {
int j = 0;
Node p = head;
while (p != null && j < i) {
p = p.next;
j++;
}
if (p == null)
throw new Exception("第" + i + "个元素不存在");
return p;
}
- 在线性表第i个元素之前插入数据为x的结点代码块
public void insert(int i, Object x) throws Exception {
Node p = (Node) get(i - 1);
Node s = new Node(x);
s.next = p.next;
p.next = s;
}
- 在结点p之后插入一个数据值为x的结点代码块
public void insert(Node p, Object x) throws Exception {
Node s = new Node(x);
Node q = head;
while (q.next != p)
q = q.next;
s.next = p.next;
p.next = s;
}
- 删除线性表的第i个元素代码块
public void remove(int i) throws Exception {
Node p = (Node) get(i - 1);//定位第i-1个结点
remove(p);//
}
- 删除结点q的直接后继代码块
public void remove(Node q) throws Exception {
Node s = q.next;
q.next = s.next;
}
- 显示线性表的数据元素值代码块
public void display() {
Node node = head.next;
while (node != null) {
if (node == head.next) {
System.out.print("head->"+node.data);
} else
System.out.print("->" + node.data);
node = node.next;// 取下一个结点
}
}
测试类:
public class Demo1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("*****主菜单*****");
System.out.println("1:利用尾插法创建一个单链表");
System.out.println("2:利用头插法创建一个单链表");
System.out.println("3、退出系统");
System.out.print("请输入你想选择的功能:");
int choice = input.nextInt();
// 创建Linklist的对象
Linklist list = new Linklist();
switch (choice) {
case 1:
// 采用尾插法创建单链表
list.creatR();
System.out.println("使用尾插法创建的单链表如下所示:");
// 显示所创建的链表
list.display();
break;
case 2:
// // 采用头插法创建单链表
list.creatH();
System.out.println("使用头插法创建的单链表如下所示:");
// // 显示所创建的链表
list.display();
break;
case 3:
System.exit(0);
break;
default:
System.out.println("请输入正确的指令!");
System.out.println("");
}
while (true) {
System.out.println("--------------------");
System.out.println("1、显示该链表的长度");
System.out.println("2、在单链表的第i个位置插入数据值为x的元素");
System.out.println("3、删除单链表中的第i个结点");
System.out.println("4、删除单链表中值为x的结点");
System.out.println("5、置空表");
System.out.println("6、退出系统");
System.out.println("请输入你想选择的功能:");
int function = input.nextInt();
switch (function) {
case 1:
System.out.println("单链表长度为:" + list.length());
break;
case 2:
System.out.println("请输入要插入的位置:");
int i = input.nextInt();// 输入想要插入的结点位置
System.out.println("请输入要插入元素的数据值:");
Object x = input.next();// 输入想要插入的值
try {
list.insert(i, x);// 调用方法
list.display();
System.out.println("");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case 3:
System.out.println("----删除单链表中第i个结点----");
i = input.nextInt();// 输入想要删除的结点位置
try {
list.remove(i);
list.display();
System.out.println("");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case 4:
System.out.println("----删除单链表中值为x的结点----");
System.out.println("请输入想要删除的结点的值:");
// list.remove(q, x);
try {
x = input.next();
int a = (Integer) list.indexOf(x);
//Node q =(Node) list.indexOf(x);
list.remove(a);
list.display();
System.out.println("");
// list.remove(q);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
case 5:
list.clear();
System.out.println("链表已置空!");
break;
case 6:
System.exit(0);
break;
default:
System.out.println("请输入正确的指令!");
}
}
}
}
测试功能一切正常,基本运算没有完全加到测试类里面,该文章仅供自己复习和提供一些思路给大家,如果有发现的错误,麻烦大家及时指出。