链表操作实例
链表中的每个结点都应包括如下内容:
- 数据部分,保存的是该结点的实际数据
- 地址部分,保存的是下一个结点的地址
链表结构的最大好处是结点之间不要求连续存放,但是浪费存储空间,且对于链表的访问只能从表头逐个查找。
链表结构还可以分为如下几类:
- 单链表
- 双链表
- 单循环链表
- 多重链的循环链表
链表常用操作有:追加结点、插入结点、查找结点、删除结点、计算链表程度、遍历结点等
链表操作实例代码如下:
package com.company.dataStructure;
import java.util.Scanner;
class DATA2 {
String key; //结点的关键字
String name;
int age;
}
class CLType { //定义链表结构
DATA2 nodeData = new DATA2();
CLType nextNode;
CLType CLAddEnd(CLType head, DATA2 nodeData) { //追加结点
CLType node, htemp;
if ((node = new CLType()) == null) {
System.out.print("申请内存失败!\n");
return null;
} else {
node.nodeData = nodeData; //保存数据
node.nextNode = null; //设置结点引用为空,即为表尾
if (head == null) {
head = node;
return head;
}
htemp = head;
while (htemp.nextNode != null) { //查找链表的结尾
htemp = htemp.nextNode;
}
htemp.nextNode = node;
return head;
}
}
CLType CLAddFirst(CLType head, DATA2 nodeData) {
CLType node;
if ((node = new CLType()) == null) {
System.out.print("申请内容失败\n");
return null;
} else {
node.nodeData = nodeData; //保存数据
node.nextNode = head;//指向头引用所指结点
head = node;//头引用指向新增结点
return node;
}
}
CLType CLFindNode(CLType head, String key) { //查找结点
CLType htemp;
htemp = head; //保存链表头引用
while (htemp != null) {//若结点有效,则进行查找
if (htemp.nodeData.key.compareTo(key) == 0) {//若结点关键字与传入关键字相同
return htemp;
}
htemp = htemp.nextNode; //处理下一结点
}
return null;
}
CLType CLInsertNode(CLType head, String findkey, DATA2 nodeData) { //插入结点
CLType node, nodetemp;
if ((node = new CLType()) == null) {
System.out.print("申请内存失败!\n");
return null;
}
node.nodeData = nodeData; //保存结点中的数据
nodetemp = CLFindNode(head, findkey);
if (nodetemp != null) { //若找到要插入的结点
node.nextNode = nodetemp.nextNode; //新插入结点指向关键结点的下一结点
nodetemp.nextNode = node;//设置关键结点指向新插入结点
} else {
System.out.print("未找到正确的插入位置!\n");
}
return head; //返回头引用
}
int CLDeleteNode(CLType head, String key) { //删除结点
CLType node, htemp; //node保存删除结点的前一个结点
htemp = head;
node = head;
while (htemp != null) {
if (htemp.nodeData.key.compareTo(key) == 0) { //找到关键字,执行删除操作
node.nextNode = htemp.nextNode; //使前一个结点指向当前结点的下一个结点
return 1;
} else {
node = htemp; //指向当前结点
htemp = htemp.nextNode; //指向下一个结点
}
}
return 0; //未删除
}
int CLLength(CLType head) { //计算链表长度
CLType htemp;
int Len = 0;
htemp = head;
while (htemp != null) {
Len++; //累加结点数量
htemp = htemp.nextNode;//处理下一个结点
}
return Len;
}
void CLAllNode(CLType head) {//遍历链表
CLType htemp;
DATA2 nodeData;
htemp = head;
System.out.printf("当前链表共有%d个结点。链表所有数据如下:\n", CLLength(head));
while (htemp != null) {
nodeData = htemp.nodeData;
System.out.printf("结点(%s,%s,%d)\n", nodeData.key, nodeData.name, nodeData.age);
htemp = htemp.nextNode;
}
}
}
public class LinkList {
public static void main(String[] args) {
CLType node, head = null;
CLType CL = new CLType();
String key, findkey;
Scanner input = new Scanner(System.in);
System.out.print("链表测试。先输入链表中的数据,格式为:关键字 姓名 年龄\n");
do {
DATA2 nodeData = new DATA2();
nodeData.key = input.next();
if (nodeData.key.equals("0")) {
break;
} else {
nodeData.name = input.next();
nodeData.age = input.nextInt();
head = CL.CLAddEnd(head, nodeData); //在链表尾部添加结点
}
} while (true);
CL.CLAllNode(head); //显示所有结点
System.out.printf("\n演示插入结点,输入插入位置的关键字:");
findkey = input.next();
System.out.print("输入插入结点的数据(关键字 姓名 年龄):");
DATA2 nodeData = new DATA2();
nodeData.key = input.next();
nodeData.name = input.next();
nodeData.age = input.nextInt();
head = CL.CLInsertNode(head, findkey, nodeData);//调用插入函数
CL.CLAllNode(head); //显示所有结点
System.out.print("\n演示删除结点,输入要删除的关键字:");
key = input.next(); //输入删除结点关键字
CL.CLDeleteNode(head, key);//调用删除结点函数
CL.CLAllNode(head);
System.out.printf("\n演示在链表中查找,输入查找关键字:");
key = input.next();
node = CL.CLFindNode(head, key);
if (node != null) {
nodeData = node.nodeData;
System.out.printf("关键字%s对应的结点为(%s,%s,%d)\n", key, nodeData.key, nodeData.name, nodeData.age);
} else {
System.out.printf("在链表中未找到关键字为%s的结点!\n", key);
}
}
}