链表实现
- 去年重学数据结构时候敲得一段代码,
- 觉得里面的原地逆转的算法觉得非常强大,想拿出来分享,内容包括创建一个链表,排序,逆序,打印等。
代码实现
package useful;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
* 链表类实现,TestList类
* @author Gastby
* 测试类,用来实现链表的各类操作,增,删,查,改,适合小白上手
*/
public class TestList {
/**
* 链表的每一个节点的基本类,用于定义每一个节点的具体信息,内部类
* @author Gastby
* 内部类,实话说当时并不太懂内部类的很多具体细节,只是觉得这个类放到测试类内部会好些(现在也还是不太懂,具体可参见设计模式这本书)
*/
class Node {
String name; //节点名名称
double data; //存放数据
Node link; //存放下一节点指针域
/**
* 构造函数,下同
* @param data 输入该节点数值
*/
Node(double data) {
this.data = data;
}
Node(String name , double data) {
this.name = name;
this.data = data;
}
}
/**
* 链表的头节点
*/
Node header = null;
public static void main(String[] args) throws Exception {
TestList p = new TestList() ;
p.header = creatTestList();
p.showTestList();
//p.reverse();
//p.showTestList();
//p.sortNode();
//p.showTestList();
//p.reverse();
//p.showTestList();
//p.insertNode();
//p.showTestList();
p.deleteNode();
p.showTestList();
}
/**
* 删除链表的头节点
* @return
* @throws Exception
*/
public double deleteNode() throws Exception {
if(header == null) {
throw new Exception("出错啦~空链表!");
}
else {
Node temp = header;
header = header.link;
return temp.data;
}
}
/**
* 插入链表节点
* @param d 要插入链表的新节点的数值
*/
public void insertNode(double d) {
System.out.println("添加链表节点,请输入新添加的链表节点的数值...\n");
Node temp = new Node(d);
temp.link = header;
header = temp;
}
/**
* 默认插入一个待从console栏输入的节点数值,好久以前写的代码啊,都没考虑流的关闭等,以及输入报错等。
*/
public void insertNode() {
Scanner s = new Scanner(System.in);
System.out.println("添加链表节点,请输入新添加的链表节点的数值...\n");
double d = s.nextDouble();
Node temp = new Node(d);
temp.link = header;
header = temp;
}
/**
* 链表按数值大小排序方法
*/
private void sortNode() {
if(header != null) {
Node base = header , move;
while(base.link != null) {
double temp;
move = base.link;
while(move != null) {
if(move.data < base.data) {
temp = move.data;
move.data = base.data;
base.data = temp;
}
move = move.link;
}
base = base.link;
}
}
}
/**
* 打印,显示一个链表的方法
*/
public void showTestList() {
Node temp = header;
if(temp != null) {
int i = 1;
System.out.println();
System.out.println("打印链表如下:\n");
while(temp != null) {
System.out.printf("打印链表的第%d个数值如下 %6.2f\n" , i , temp.data);
temp = temp.link;
i++;
}
}
}
/**
* 从console栏输入数值,然后建立一个链表
* @return
*/
public static Node creatTestList() {
Node p = null;
int i = 1;
do{
System.out.printf("创建一个链表,请输入第%d个链表数值,停止输入请输‘0’结束...\n" , i);
Scanner s = new Scanner(System.in);
double temp;
try {
temp = s.nextDouble();
} catch (InputMismatchException f) {
break;
}
if(temp != 0) {
TestList.Node tempNode = new TestList().new Node(temp);
tempNode.link = p;
p = tempNode;
}
else
break;
i++;
}while(true);
TestList test = new TestList();
test.header = p;
test.reverse();
p = test.header;
return p;
}
/**逆转一个链表, 经典的原地逆转算法
* 无返回数值
*/
private void reverse() {
Node p , q , r;
p = header;
q = null;
while(p != null) {
r = q;
q = p;
p = p.link;
q.link = r;
}
header = q;
}
/**
* 求算链表节点数
* @return 返回数值
*/
private int countTestListNum() {
Node temp = header;
int i = 0;
while(temp != null) {
i++;
temp = temp.link;
}
return i;
}
}
真的觉得当初敲得这些代码很小白啊,很多地方都值得优化,也才一年,继续学习!争取格式,或者是代码质量都得到提高。