链表
链表是有序的,但内存存放地址是不连续的,说它连续是指逻辑上连续,也就是每个元素知道后面是谁或者前后都知道,是按照顺序排列的。
链表的每个节点包含一个data域,一个next域。
链表分别带头结点的链表和不带头结点的链表。
下文介绍的是带头结点的,头结点不存储数据。
下面实现的是单链表:
说下单链表增加元素的思路,如下图:
删除元素思路:
修改和遍历很简单,所以不画图了,大概就是遍历链表找到就对其修改,直接上代码:
class SingleNode{
//id和name是data域
private int id;
private String name;
public SingleNode(int id,String name){
this.id = id;
this.name = name;
}
public SingleNode next;
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class SingleLinkedList{
public SingleLinkedList(){
head = new SingleNode(0,"");
}
public SingleNode head;
public void addNode(SingleNode node){
SingleNode temp = head;
while(null != temp.next){
if(node.getId()==temp.next.getId()){
System.out.println("编号已存在!");
return;
}
if(node.getId()<temp.next.getId()){
break;
}
temp = temp.next;
}
if(null == temp.next){
temp.next = node;
System.out.println("编号成功添加!");
}else{
node.next = temp.next;
temp.next = node;
System.out.println("编号成功添加!");
}
}
public void deleteNode(SingleNode node){
SingleNode temp = head;
boolean isFound = false;
while(null != temp.next){
if(node.getId()==temp.next.getId()){
isFound = true;
break;
}
temp = temp.next;
}
if(isFound){
temp.next = temp.next.next;
System.out.println("编号已删除!");
}else{
System.out.println("编号不存在!");
}
}
public void updateNode(SingleNode node){
SingleNode temp = head.next;
boolean isFound = false;
while(null != temp){
if(node.getId()==temp.getId()){
isFound = true;
break;
}
temp = temp.next;
}
if(isFound){
temp.setName(node.getName());
System.out.println("修改成功!");
}else{
System.out.println("不存在该数据无法修改");
}
}
public void printList(){
SingleNode temp = head.next;
while(null != temp){
System.out.println("编号" + temp.getId() + "姓名" + temp.getName());
temp = temp.next;
}
}
}
public class SingleLinkedListDemo {
public static void main(String[] args){
SingleLinkedList list = new SingleLinkedList();
SingleNode s1 = new SingleNode(3,"003");
SingleNode s2 = new SingleNode(7,"007");
SingleNode s3 = new SingleNode(15,"015");
SingleNode s4 = new SingleNode(24,"024");
SingleNode s5 = new SingleNode(32,"032");
list.addNode(s3);
list.addNode(s1);
list.addNode(s4);
list.addNode(s2);
list.addNode(s5);
list.printList();
list.addNode(new SingleNode(12,"012"));
list.printList();
list.deleteNode(new SingleNode(24,"012"));
list.updateNode(new SingleNode(15,"151515"));
list.printList();
}
}
测试结构如下:
下面增加几个方法:
第一个:反转链表(改变链表结构)
public static SingleLinkedList reverseList(SingleLinkedList sList) {
SingleNode cur = sList.head.next;
SingleNode next;
SingleNode reverseNode = new SingleNode(0, "");
if (null == cur || null == cur.next) {
return sList;
}
while (null != cur) {
next = cur.next;
cur.next = reverseNode.next;
reverseNode.next = cur;
cur = next;
}
sList.head.next = reverseNode.next;
return sList;
}
第二个:反向输出链表(不改变链表)
public static void reversePrint(SingleLinkedList sList) {
Stack stk = new Stack();
SingleNode cur = sList.head.next;
while (null != cur) {
stk.push(cur);
cur = cur.next;
}
for (int i = 0; i < stk.size(); i++) {
SingleNode s = (SingleNode) stk.pop();
System.out.println(s.getName() + "\t");
}
}
第三个:合并两个有序列表
public static SingleLinkedList mergeList(SingleLinkedList sList1, SingleLinkedList sList2) {
SingleNode head1 = sList1.head;
SingleNode head2 = sList2.head.next;
boolean isFinished = false;
while (null != head1.next) {
if (null == head2) {
isFinished = true;
break;
}
if (head2.getId() < head1.next.getId()) {
SingleNode temp2 = head2.next;
head2.next = head1.next;
head1.next = head2;
head1 = head2;
head2 = temp2;
if (null == head2) {
break;
}
} else if (head2.getId() > head1.next.getId()) {
head1 = head1.next;
} else if (head2.getId() == head1.next.getId()) {
head1 = head1.next;
head2 = head2.next;
}
}
if (!isFinished) {
head1.next = head2;
}
return sList1;
}