您的位置:首页 > 其它

双向链表的实现

2011-12-22 08:47 190 查看
/*  单链式存储结构中,只有一个指向后继的指针,从某点出发,只能顺序的访
访问,如果想访问上一个结点必须从头开始,时间复杂度:访问下一个结点
为O(1),访问上一个结点为O(n)而双向链表可以克服这个问题
双向链表的结点存在一个数据域和两个指针域:一个指向前驱一个指向后继 */
#ifndef DOUBLELINKLIST_H
#define DOUBLELINKLIST_H
typedef int ElemType; //链表的数据类型
typedef struct node{  //链表结点
ElemType data; //链表的数据域
struct node *next; //链表的指针域,指向后继
struct node *prev; //链表的指针域,指向前驱
}LinkNode,*LinkList;
void InitList(LinkList *l); //初始化链表
void CreateList(LinkList l); //创建一个双向链表
void InsertList(LinkList l,int i,ElemType e); //在双向链表的第i个位置插入元素
void DeleteList(LinkList l,int i); //删除双向链表的第i个位置的元素
void DestroyList(LinkList l); //销毁双向链表
//bool Find(LinkList l,ElemType e); //在双向链表中查找元素看是否存在
void Print(LinkList l); //输出双向链表
int GetListLength(LinkList l); //获取链表的长度
#endif //DOUBLELINKLIST_H


#include "DoubleLinkList.h"
#include <stdio.h>
#include <stdlib.h>
void InitList(LinkList *l) //初始化双向链表
{
(*l) = (LinkList)malloc(sizeof(LinkNode)); //创建头结点,使l成为指向头结点的指针
(*l)->next = (*l)->prev = NULL; //初始化头结点的两个指针域为NULL
}
void CreateList(LinkList l) //创建一个双向链表
{
LinkList order = l;
printf("请输入双向链表的数据:\n");
int data;
while((scanf("%d",&data)) != EOF)
{
LinkList temp = (LinkList)malloc(sizeof(LinkNode)); //创建新结点
if(temp) //如果内存分配成功
{
temp->data = data;	 //初始化新结点的数据
temp->next = order->next; //使新结点的指针域指向当前结点所指向的结点
if(order == l) //如果temp是第一个结点,则他的指向前驱的指针是NULL
temp->prev = NULL;
else			//否则就指向当前的结点
temp->prev = order;
order->next = temp; //当前结点的后继指针域指向新结点
order = order->next; //指向当前结点的指针指向新结点
}
}
}
void InsertList(LinkList l,int i,ElemType e) //在链表的第i个位置插入元素e
{
if(i < 1 || i > GetListLength(l) + 1) //超出范围返回
return;
LinkList temp = l;
for(int j = 0;j < i - 1;++j) //循环到要插入的位置的前一个位置
temp = temp->next;
LinkList tp = (LinkList)malloc(sizeof(LinkNode)); //创建新结点
if(tp) //如果内存分配成功
{
tp->data = e; //初始化新结点的数据
tp->next = temp->next; //初始化新结点的后继指针域
temp->next->prev = tp; //使当前结点的后继结点的前驱指针域指向新结点
temp->next = tp; //当前结点指向的后继指针域指向新结点
tp->prev = temp; //新结点的后继指针域指向当前结点
}
}
void DeleteList(LinkList l,int i) //删除链表第i个位置的元素
{
if(i < 1 || i > GetListLength(l)) //超出范围返回
return;
LinkList temp = l;
for(int j = 0;j < i;++j) //遍历到要删除的位置
temp = temp->next;
temp->prev->next = temp->next; //使要删除结点的前驱的后继指针指向要删除的结点的后继结点
temp->next->prev = temp->prev; //使要删除结点的后继结点的前驱指针指向要删除结点的后继结点
free(temp); //释放空间
}
int GetListLength(LinkList l) //返回链表的长度
{
int i = 0;
LinkList temp = l->next;
while(temp) //遍历获取长度
{
temp = temp->next;
++i;
}
return i;
}
void DestroyList(LinkList l) //销毁链表
{
LinkList  temp = l->next;
while(temp) //遍历销毁结点
{
LinkList tp = temp;
temp = temp->next;
free(tp);
}
free(l);
}
void Print(LinkList l) //打印链表
{
LinkList temp = l->next;
while(temp)
{
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}


#include "DoubleLinkList.h"
#include <stdio.h>
int main()
{
LinkList l;
InitList(&l);
CreateList(l);
Print(l);
printf("在链表的第2个位置插入元素:5\n");
InsertList(l,2,5);
Print(l);
printf("删除链表的第3个位置的元素:\n");
DeleteList(l,3);
Print(l);
DestroyList(l);
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: