双链表,又称双向链表。顾名思义,和单链表的数据组织形式一样,有指针域和数据域。只不过和单链表不同的是双链表拥有两个指针域分别指向前驱结点(直接前驱)和后继结点(直接后继)。因此与单链表相比,双链表中访问一个结点的前、后结点更方便。
以下就是带头结点的双链表的不同代码实现:
C语言(DoubleLinkedList)
#ifndef DOUBLELINKEDLIST_H_INCLUDED
#define DOUBLELINKEDLIST_H_INCLUDED
typedef int ElemType;
typedef struct Node
{
ElemType elem;
struct Node *prior;
struct Node *next;
}LNode,*LinkedList;
void InitList(LinkedList *L)
{
(*L)=(LNode*)malloc(sizeof(LNode));
(*L)->next=NULL;
(*L)->prior=NULL;
}
void DestroyList(LinkedList *L)
{
LNode *p=(*L);
while((*L)!=NULL)
{
p=(*L);
(*L)=p->next;
free(p);
p=NULL;
}
}
void ClearList(LinkedList *L)
{
LNode *p=(*L);
while(p->next!=NULL)
{
p=(*L)->next;
(*L)->next=p->next;
free(p);
}
}
int ListEmpty(LinkedList *L)
{
if((*L)->next!=NULL)
{
return 0;
}
else
{
return 1;
}
}
int ListLength(LinkedList *L)
{
LNode *p=(*L);
int i=0;
while(p->next!=NULL)
{
p=p->next;
i++;
}
return i;
}
ElemType GetElem(LinkedList *L,int index)
{
if(index<0||index>=ListLength(L))
{
return -1;
}
else
{
LNode *p=(*L)->next;
int i=0;
while(i<index)
{
i++;
p=p->next;
}
return p->elem;
}
}
int LocateElem(LinkedList *L,ElemType elem)
{
LNode *p=(*L)->next;
int i=0;
while(i<ListLength(L)&&p!=NULL)
{
if(p->elem==elem)
{
return i;
}
p=p->next;
i++;
}
return -1;
}
ElemType PriorElem(LinkedList *L,ElemType elem)
{
LNode *p=(*L)->next;
while(p!=NULL)
{
if(p->elem==elem&&LocateElem(L,elem)!=0)
{
return p->prior->elem;
}
p=p->next;
}
return -1;
}
ElemType NextElem(LinkedList *L,ElemType elem)
{
LNode *p=(*L)->next;
while(p->next!=NULL&&LocateElem(L,elem)!=ListLength(L)-1)
{
if(p->elem==elem)
{
return p->next->elem;
}
p=p->next;
}
return -1;
}
void addFirst(LinkedList *L,ElemType elem)
{
LNode *s,*p=(*L);
s=(LNode*)malloc(sizeof(LNode));
s->elem=elem;
s->next=p->next;
p->next=s;
s->prior=p;
if(s->next!=NULL)
{
s->next->prior=s;
}
}
void addAfter(LinkedList *L,ElemType elem)
{
LNode *p=(*L),*s;
while(p->next!=NULL)
{
p=p->next;
}
s=(LNode*)malloc(sizeof(LNode));
s->elem=elem;
s->next=p->next;
s->prior=p;
p->next=s;
}
int ListInsert(LinkedList *L,int index,ElemType elem)
{
if(index<0||index>ListLength(L))
{
return -1;
}
else if(index==0)
{
addFirst(L,elem);
return 1;
}
else
{
LNode *p=(*L),*s;
int i=0;
while(i<index)
{
p=p->next;
i++;
}
s=(LNode*)malloc(sizeof(LNode));
s->elem=elem;
s->next=p->next;
s->prior=p;
p->next=s;
if(s->next!=NULL)
{
s->next->prior=s;
}
return 1;
}
}
int ListDelete(LinkedList *L,int index)
{
if(index<0||index>=ListLength(L))
{
return -1;
}
else if(index==ListLength(L)-1)
{
LNode *p=(*L),*del;
int i=0;
while(i<index)
{
p=p->next;
i++;
}
del=p->next;
del->prior->next=NULL;
del->prior=NULL;
free(del);
}
else
{
LNode *p=(*L),*del;
int i=0;
while(i<index)
{
p=p->next;
i++;
}
del=p->next;
del->prior->next=del->next;
del->next->prior=del->prior;
free(del);
}
return 1;
}
void TraverseList(LinkedList *L)
{
LNode *p=(*L)->next;
while(p!=NULL)
{
printf("%d\t",p->elem);
p=p->next;
}
printf("\n");
}
void TraverseListByReverseOrder(LinkedList *L)
{
if(ListEmpty(L))
{
printf("\n");
}
else
{
LNode *p=(*L)->next;
while(p->next!=NULL)
{
p=p->next;
}
while(p->prior!=NULL)
{
printf("%d\t",p->elem);
p=p->prior;
}
printf("\n");
}
}
#endif // DOUBLELINKEDLIST_H_INCLUDED
C语言测试用例代码:
#include <stdio.h>
#include <stdlib.h>
#include <C:\Users\12952\Desktop\testc\DoubleLinkedList.h>
int main()
{
LinkedList list;
while(1)
{
printf("1:初始化顺序表 2:销毁顺序表 3:清理顺序表 4:判断表空\n5:返回表长 6:利用下标获取元素值 7:返回元素的位置 8:返回前驱元素\n9:返回后继元素 10:插入顺序表 11:删除表元素 12:遍历线性表\n13:前插元素 14:后插元素 15:逆序遍历线性表\n请选择操作选项:\n");
int op;
scanf("%d",&op);
switch(op)
{
case 1:
{
InitList(&list);
break;
}
case 2:
{
DestroyList(&list);
break;
}
case 3:
{
ClearList(&list);
break;
}
case 4:
{
if(ListEmpty(&list)==1)
{
printf("表为空\n");
}
else
{
printf("表不为空\n");
}
break;
}
case 5:
{
printf("表长为:%d\n",ListLength(&list));
break;
}
case 6:
{
printf("请输入下标值:");
int get;
scanf("%d",&get);
if(GetElem(&list,get)!=-1)
{
printf("下标值%d对应的元素值为:%d\n",get,GetElem(&list,get));
}
else
{
printf("无此元素\n");
}
break;
}
case 7:
{
printf("请输入元素值:");
int get;
scanf("%d",&get);
if(LocateElem(&list,get)!=-1)
{
printf("元素%d对应的下标值为:%d\n",get,LocateElem(&list,get));
}
else
{
printf("无此元素\n");
}
break;
}
case 8:
{
printf("请输入元素值:");
int get;
scanf("%d",&get);
if(PriorElem(&list,get)!=-1)
{
printf("元素%d对应的前驱元素为:%d\n",get,PriorElem(&list,get));
}
else
{
printf("无此元素\n");
}
break;
}
case 9:
{
printf("请输入元素值:");
int get;
scanf("%d",&get);
if(NextElem(&list,get)!=-1)
{
printf("元素%d对应的后继元素为:%d\n",get,NextElem(&list,get));
}
else
{
printf("无此元素\n");
}
break;
}
case 10:
{
printf("请输入元素值:");
int get;
scanf("%d",&get);
printf("请输入元素的位置:");
int get1;
scanf("%d",&get1);
if(ListInsert(&list,get1,get)==1)
{
printf("元素插入成功.\n");
TraverseList(&list);
}
else
{
printf("插入失败\n");
}
break;
}
case 11:
{
printf("请输入下标值:");
int get;
scanf("%d",&get);
if(ListDelete(&list,get)==1)
{
printf("已删除元素\n");
TraverseList(&list);
}
else
{
printf("未找到此元素\n");
}
break;
}
case 12:
{
printf("表中元素如下:\n");
TraverseList(&list);
break;
}
case 13:
{
printf("请输入元素的值:");
int get;
scanf("%d",&get);
addFirst(&list,get);
TraverseList(&list);
break;
}
case 14:
{
printf("请输入元素的值:");
int get;
scanf("%d",&get);
addAfter(&list,get);
TraverseList(&list);
break;
}
case 15:
{
printf("表中元素如下:\n");
TraverseListByReverseOrder(&list);
break;
}
}
}
return 0;
}
Java代码:
package DataStructure.LinearList;
public class LinkedList1 {
protected Object elem;
protected LinkedList1 next;
protected LinkedList1 prior;
public LinkedList1(Object elem)
{
this.elem=elem;
}
public LinkedList1(){}
}
package DataStructure.LinearList;
public class DoubleLinkedList {
private LinkedList1 list;
private LinkedList1 head;
public void InitList()
{
list=new LinkedList1();
this.head=list;
list.next=null;
list.prior=null;
list.elem=null;
}
public Boolean DestoryList()
{
ClearList();
head.next=null;
head.prior=null;
head=null;
return true;
}
public Boolean ClearList()
{
LinkedList1 pre=head;
LinkedList1 temp=pre.next;
while (temp!=null)
{
pre.elem=null;
pre.prior=null;
pre.next=null;
pre=temp;
temp=temp.next;
}
return true;
}
public Boolean ListEmpty()
{
if (head.next!=null)
{
return false;
}
else
{
return true;
}
}
public int ListLength()
{
LinkedList1 temp=head;
int i=0;
while (temp.next!=null)
{
i++;
temp=temp.next;
}
return i;
}
public Object GetElem(int index)
{
if(index<0||index>=this.ListLength())
{
return -1;
}
else {
LinkedList1 temp=head;
int i=0;
while (i<index)
{
i++;
temp=temp.next;
}
return temp.elem;
}
}
public int LocateElem(Object elem)
{
LinkedList1 temp=head;
for(int i=0;i<this.ListLength();i++)
{
if (temp.elem.equals(elem))
{
return i;
}
else
{
temp=temp.next;
}
}
return -1;
}
public Object PriorElem(Object elem)
{
int i=0;
LinkedList1 temp=head;
while (i<this.ListLength())
{
if (temp.elem.equals(elem))
{
try {
return temp.prior.elem;
}
catch (NullPointerException e)
{
return -1;
}
}
else
{
temp=temp.next;
}
i++;
}
return -1;
}
public Object NextElem(Object elem)
{
int i=0;
LinkedList1 temp=head;
while (i<this.ListLength()-1)
{
if (temp.elem.equals(elem))
{
return temp.next.elem;
}
else
{
temp=temp.next;
}
i++;
}
return -1;
}
public Boolean ListInsert(Object elem,int index)
{
if(index<0||index>this.ListLength())
{
return false;
}
LinkedList1 temp=head;
LinkedList1 node=new LinkedList1(elem);
if(index==0)
{
node.next=temp;
temp.prior=node;
node.prior=null;
head=node;
return true;
}
if(index>0)
{
int i=1;
while(i<index)
{
temp=temp.next;
i++;
}
node.next=temp.next;
temp.next.prior=node;
temp.next=node;
node.prior=temp;
}
return true;
}
public void addFirst(Object elem)
{
LinkedList1 node=new LinkedList1(elem);
node.next = head;
head.prior=node;
head=node;
}
public void addAfter(Object elem)
{
int i=0;
LinkedList1 temp=head;
if (this.ListLength()==0)
{
addFirst(elem);
}
else
{
while (i<this.ListLength()-1)
{
temp=temp.next;
i++;
}
LinkedList1 node=new LinkedList1(elem);
node.next=temp.next;
temp.next.prior=node;
temp.next=node;
node.prior=temp;
}
}
public Boolean DeleteElem(int index)
{
if(index<0||index>this.ListLength()-1)
{
return false;
}
if(index==0)
{
LinkedList1 pre=head;
LinkedList1 temp=pre.next;
temp.prior=null;
head=temp;
pre=null;
return true;
}
else
{
LinkedList1 temp=head;
for (int i = 0; i < index-1; i++) {
temp=temp.next;
}
LinkedList1 delete=temp.next;
temp.next=delete.next;
delete.next.prior=temp;
delete.next=null;//可有可无
delete.prior=null;//可有可无
return true;
}
}
public void TraverseList()
{
LinkedList1 temp=head;
while(temp.next!=null)
{
System.out.print(temp.elem+"\t");
temp=temp.next;
}
System.out.println("");
}
public void TraverseListByReverseOrder()
{
int i=0;
LinkedList1 temp=head;
while (i<this.ListLength()-1)
{
temp=temp.next;
i++;
}
while (temp!=null)
{
System.out.print(temp.elem+"\t");
temp=temp.prior;
}
System.out.println("");
}
}
Java测试用例代码:
import DataStructure.LinearList.DoubleLinkedList;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
DoubleLinkedList list=new DoubleLinkedList();
Scanner sc=new Scanner(System.in);
int op;
while (true)
{
System.out.println("1:初始化线性表;2:销毁线性表;3:清理线性表;4:判断表空;5:返回表长;6:按下标值获取元素;7:返回元素所在位置;" +
"8:返回前驱元素;9:返回后继元素;10:插入线性表;11:前插元素;12:后插元素;13:按下标值删除元素;14:遍历线性表;15:逆序遍历线性表");
System.out.println("请输入操作选项:");
op=sc.nextInt();
switch (op)
{
case 1:
{
list.InitList();
System.out.println("初始化完成");
break;
}
case 2:
{
list.DestoryList();
System.out.println("销毁完成");
break;
}
case 3:
{
list.ClearList();
System.out.println("清理完成");
break;
}
case 4:
{
if(list.ListEmpty())
{
System.out.println("表为空");
}
else
{
System.out.println("表不为空");
}
break;
}
case 5:
{
System.out.printf("表长为:%d\n",list.ListLength());
break;
}
case 6:
{
System.out.print("请输入下标值:");
int getch=sc.nextInt();
System.out.println("下标"+getch+"对应的元素值为:"+list.GetElem(getch));
break;
}
case 7:
{
System.out.print("请输入元素值:");
Object getch=sc.nextInt();
System.out.println("元素"+getch+"对应的下标为:"+list.LocateElem(getch));
break;
}
case 8:
{
System.out.print("请输入元素值:");
Object getch=sc.nextInt();
if((int)list.PriorElem(getch)!=-1)
{
System.out.println("元素"+getch+"对应的前驱元素为:"+list.PriorElem(getch));
}
else
{
System.out.println("无此元素");
}
break;
}
case 9:
{
System.out.print("请输入元素值:");
Object getch=sc.nextInt();
if((int)list.NextElem(getch)!=-1)
{
System.out.println("元素"+getch+"对应的后继元素为:"+list.NextElem(getch));
}
else
{
System.out.println("无此元素");
}
break;
}
case 10:
{
System.out.print("请输入要插入的元素:");
int getch=sc.nextInt();
System.out.print("请输入插入的位置:");
int getch1= sc.nextInt();
if (list.ListInsert(getch,getch1))
{
System.out.println("插入成功");
list.TraverseList();
}
else
{
System.out.println("插入失败");
list.TraverseList();
}
break;
}
case 11:
{
System.out.print("请输入要插入的元素值:");
Object getch=sc.nextInt();
list.addFirst(getch);
list.TraverseList();
break;
}
case 12:
{
System.out.print("请输入要插入的元素值:");
Object getch=sc.nextInt();
list.addAfter(getch);
list.TraverseList();
break;
}
case 13:
{
System.out.print("请输入下标值:");
int getch=sc.nextInt();
list.DeleteElem(getch);
list.TraverseList();
break;
}
case 14:
{
System.out.println("元素如下:");
list.TraverseList();
break;
}
case 15:
{
System.out.println("元素如下:");
list.TraverseListByReverseOrder();
break;
}
}
}
}
}