双向链表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向链表相关的知识,希望对你有一定的参考价值。
意义:
解决单链表的由于方向性引起的效率问题
单链表有个缺陷,就是当数据量比较大的时候,当需要对已知节点做删除,排序的等操作时,有一个问题,就是当需要从头节点开始遍历,往往效率较低,
head==>1 ==> 2 ==>3 ==>4==5
当我需要删除3这个结点时,就得知道2这个结点的指针,但是只能从头指针开始遍历,才能知道
双向链表的指针域,除了包含一个后继指针外还包括一个前驱指针,这样子,当拥有一个已知结点时,就不要从头遍历就可以知道这个指针的前驱指针,直接使用即可
head<==> 1<==>2<==>3
当已知3这个结点时,可以通过前驱指针,得到2这个结点的指针,然后可以做相应的处理
2.实现
2.1 数据结构
typedef struct node
{
int data; //数据域
struct node *next; //指针域
struct node *prep;
}NODE_t;
next 为后继指针,prep为前驱指针
2.2 创建
NODE_t *CreatNodeList()
{
NODE_t *head = NULL;
head = (NODE_t *)malloc(sizeof(NODE_t));
if(!head)
exit(-1);
head->next = NULL;
head->prep = NULL;
return head;
}
2.2 插入
int InsertNode(NODE_t *head,int data)
{
NODE_t *cur = NULL;
if(!head)
exit(-1);
cur = (NODE_t *)malloc(sizeof(NODE_t));
if(!cur)
exit(-1);
cur->data = data;
if(!head->next)
{
// 当只有头节点时
cur->next = head->next;
cur->prep = head;
head->next = cur;
}
else
{
// 当链表有节点元素时
cur->next = head->next;
head->next->prep = cur;
cur->prep = head;
head->next = cur;
}
return 0;
}
2.3 查找
NODE_t *findNode(NODE_t *head,int data)
{
head = head->next;
while(head)
{
if(head->data == data)
{
break;
}
head = head->next;
}
if(head == NULL)
{
printf("sorry,%d is not in the list\n",data);
}
return head;
}
2.4 删除
int DeleteNodeOfList(NODE_t *head,NODE_t *pfind)
{
if(pfind->next != NULL)
{
pfind->prep->next = pfind->next;
pfind->next->prep = pfind->prep;
}
else
{
// 处理尾节点
pfind->prep->next = NULL;
}
free(pfind);
pfind = NULL;
return 0;
}
2.5 修改
int UpdateNode(NODE_t *head,int olddata,int newdata)
{
NODE_t *p = findNode(head,olddata);
if(p)
{
p->data = newdata;
}
return 0;
}
2.6 排序
int sortList(NODE_t *head)
{
int i = 0,j = 0;
int listlen = 0;
int tmpData = 0;
NODE_t *p = NULL;
// 使用冒泡排序,不动指针域,比较数据域,使用临时变量,将有大小之别的节点的数据域交换
// 得到链表长度,方便冒泡
listlen = ListNodeLen(head);
// 指到首节点
p = head->next;
for(i = 0;i < listlen-1;i++)
{
// 每一轮从头开始
p = head->next;
for(j = 0;j<listlen - i-1;j++)
{
// 将小值排在前面
if(p->data > p->next->data)
{
tmpData = p->data;
p->data = p->next->data;
p->next->data = tmpData;
}
p = p->next;
}
}
return 0;
}
以上是关于双向链表的主要内容,如果未能解决你的问题,请参考以下文章