双向链表
单链表,通过这样的链式存储,我们不用像顺序表一样一次性申请一段连续的空间,而是只需要单独为结点申请内存空间,同时在插入和删除的速度上也比顺序表轻松。不过有一个问题是,如果我们想要操作某一个结点,比如删除或是插入,那么由于单链表的性质,我们只能先去找到它的前驱结点,才能进行。
为了解决这种查找前驱结点非常麻烦的问题,我们可以让结点不仅保存指向后续结点的指针
这样我们无论哪个结点,都能快速的找到对应的前驱结点,就很方便了,这样的链表我们称为双向链表
初始化
将node->next 和 node->prev置空
插入函数
加if判断优化
完成先序逆序遍历链表
逆序先打印 后开始赋值
删除操作
代码如下
#include <stdlib.h>
#include <stdio.h>
typedef int E;
struct NodeList{
E element;
struct NodeList * next;
struct NodeList * prev;
};
typedef struct NodeList * nodelist;
//初始化函数
void initList(nodelist node){
node->next = node->prev = NULL;
}
//添加函数
int addList(nodelist node, int element, int index){
if(index < 1) return 0;
while (--index){
node = node->next;
if(node == NULL) return 0;
}
nodelist newNode = malloc(sizeof (struct NodeList));
if(newNode == NULL) return 0;
//此时存在两种情况,一种是后继结点不存在的情况,一种是后继结点存在的情况,为了优化代码需要进行if判断
if(node->next){
//若node->next存在 即后继结点存在
newNode->next = node->next; //将新插入结点的下一指向 指向所查找出来的前驱结点的下一指向
node->next->prev = newNode; //将前驱结点指向的下一结点的上一指向 指向新插入的结点
}else{
//若后继结点不存在
newNode->next = NULL; //将新插入的结点的下一个指向置为空
}
node->next = newNode;//将头结点的下一指向 指向新插入的结点
newNode->prev = node;//将新插入结点的上一指向 指向头结点
newNode->element = element;
return 1;
}
//以先序的顺序 查找函数
int searchList(nodelist node, int element){
int index = 1;
if(node->next == NULL) return 0;
while(node){
node = node->next;
if(node->element == element) return index;
index ++;
}
}
//删除函数
int deleteList(nodelist node, int element){
int index = searchList(node,element);
while(--index){
node = node->next;
if(node == NULL) return 0;
}
//若要删除的结点不存在
if(node->next == NULL) return 0;
//找到待删除的结点 以便释放内存
nodelist temp = node->next;
//考虑删除结点下一个存不存在
if(node->next->next){
node->next = node->next->next;
node->next->next->prev = node;
}else{
node->next = NULL;
}
//释放内存
free(temp);
return 1;
}
int main(){
struct NodeList node;
initList(&node);
for(int i = 1; i <= 5; i++){
addList(&node, i*i+i, i);
}
//先正向遍历
nodelist thisNode = &node;
while(thisNode->next){
thisNode = thisNode->next;
printf("%d ",thisNode->element);
}
printf("\n");
//后逆向遍历
while(thisNode->prev){
printf("%d ",thisNode->element);
thisNode = thisNode->prev;
}
printf("\n%d",searchList(&node,6));
deleteList(&node, 6);
printf("\n");
while(thisNode->next){
thisNode = thisNode->next;
printf("%d ",thisNode->element);
}
}