双向链表
- 定义
- 结构体
- 创建一个双向链表
- 展示双向链表中的数据元素
- 查找双向链表中指定位置的结点
- 向双向链表中指定位置插入结点
- 删除双向列表指定位置的的结点
1.定义
循环链表和双向链表是对单链表的改进,仍属于链存储结构
双向链表的结点包括一个数据域和两个指针域,后继指针和前继指针域
双向链表的后继链和前继首尾相连,为空双向链表,又称双向循环链表
双向链表是一种对称结构,提供了向前搜索和向后搜索两种机会,操作插入和删除操作更加便利
前驱指针 | 结点数据 | 后继指针 |
---|
2.结构体
创建结构类型,在DoubleCs.c文件中
/*
双向链表结构体
*/
typedef struct dnode{
int data;
struct dnode *prior,*next;
}DOUBLELINKLIST;
3.创建一个双向链表
在DoubleLinkList.h写出方法声明
#include "DoubleCs.c"
/*
创建一个双向链表
*/
DOUBLELINKLIST * createDoubleLinkList();
在DoubleLinkList.c中实现此方法
#include "DoubleLinkList.h"
#include <stdlib.h>
#include <stdio.h>
/*
创建一个双向链表
*/
DOUBLELINKLIST * createDoubleLinkList(){
//1.创建一个头结点
DOUBLELINKLIST * SQ;
SQ=(DOUBLELINKLIST *) malloc(sizeof(DOUBLELINKLIST));
SQ->data=-1;
SQ->prior=NULL;
SQ->next=NULL;
//2.将其赋值给一个结点,供返回
DOUBLELINKLIST *headDoubleLinkList=NULL;
//3.循环添加结点
DOUBLELINKLIST *tempNode;
int x=1;
while (x<=10) {
//3.1初始化添加的结点
tempNode=(DOUBLELINKLIST *)malloc(sizeof(DOUBLELINKLIST));
//3.2设置data数据
tempNode->data=x;
//3.3设置添加结点的前指针域值为SQ
tempNode->prior=SQ;
//3.4设置添加结点的后指针域值为NULL
tempNode->next=NULL;
//3.5设置链表的后指针域值为添加的结点
SQ->next=tempNode;
if(x==1){
//这是为了保存了头结点,供后面返回
headDoubleLinkList=SQ;
}
//3.6将临时结点赋给SQ,为了继续在后面继续添加(尾插入加载)
SQ=tempNode;
//4.数据自增
x++;
}
return headDoubleLinkList;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "DoubleLinkList.h"
int main(int argc, const char * argv[]) {
//创建一个双向链表
printf("创建一个双向链表\n");
DOUBLELINKLIST *createList=createDoubleLinkList();
if(createList!=NULL){
printf("创建双向链表成功success\n");
}
}
打印结果:
创建一个双向链表
创建双向链表成功success
4.展示双向链表中的数据元素
在DoubleLinkList.h写出方法声明
#include "DoubleCs.c"
/*
展示双向链表中的数据元素
*/
void showDoubleLinkList(DOUBLELINKLIST *SQ);
在DoubleLinkList.c中实现此方法
#include "DoubleLinkList.h"
#include <stdlib.h>
#include <stdio.h>
void showDoubleLinkList(DOUBLELINKLIST *SQ){
if(SQ==NULL){
printf("list=[链表为NULL]");
return;
}
printf("list=[");
printf("%d",SQ->data);
while (SQ->next!=NULL) {
SQ=SQ->next;
printf(",%d",SQ->data);
}
printf("]\n");
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "DoubleLinkList.h"
int main(int argc, const char * argv[]) {
//展示链表中数据
printf("输出双向链表数据\n");
showDoubleLinkList(createList);
printf("\n");
}
打印结果:
输出双向链表数据
list=[-1,1,2,3,4,5,6,7,8,9,10]
5.查找双向链表中指定位置的结点
在DoubleLinkList.h写出方法声明
#include "DoubleCs.c"
/*
查找双向链表中指定位置的结点
*/
DOUBLELINKLIST * findDoubleLinkListByPosition(DOUBLELINKLIST *SQ, int position);
在DoubleLinkList.c中实现此方法
#include "DoubleLinkList.h"
#include <stdlib.h>
#include <stdio.h>
DOUBLELINKLIST * findDoubleLinkListByPosition(DOUBLELINKLIST *SQ, int position){
//1.保证SQ是使用的头结点指针,这样才能保证是顺序查找指定位置的节点
if(SQ==NULL || SQ->next==NULL || position<=0){
return NULL;
}
int i=0;
while (SQ!=NULL && position!=i) {
i++;
SQ=SQ->next;
}
return SQ;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "DoubleLinkList.h"
int main(int argc, const char * argv[]) {
//查找双向链表中指定位置的结点
printf("查找双向链表中指定位置的结点\n");
DOUBLELINKLIST *findList=createDoubleLinkList();
showDoubleLinkList(findList);
int findPosition=3;
DOUBLELINKLIST *findNode=findDoubleLinkListByPosition(findList, findPosition);
if(findNode==NULL){
printf("list中不存在 %d 结点\n",findPosition);
}else{
printf("list中已经找到 %d 位置的结点,data=%d\n",findPosition,findNode->data);
}
printf("\n");
}
打印结果:
查找双向链表中指定位置的结点
list=[-1,1,2,3,4,5,6,7,8,9,10]
list中已经找到 3 位置的结点,data=3
6.向双向链表中指定位置插入结点
在DoubleLinkList.h写出方法声明
#include "DoubleCs.c"
/*
向双向链表中指定位置插入结点
*/
DOUBLELINKLIST *insterDoubleLinkListByPosition(DOUBLELINKLIST *SQ,int position,int insterData);
在DoubleLinkList.c中实现此方法
#include "DoubleLinkList.h"
#include <stdlib.h>
#include <stdio.h>
DOUBLELINKLIST *insterDoubleLinkListByPosition(DOUBLELINKLIST *SQ,int position,int insterData){
//1.链表的头结点赋给临时结点
DOUBLELINKLIST *temp;
temp=SQ;
//2.查找到指定位置的节点
DOUBLELINKLIST *Q2=findDoubleLinkListByPosition(temp, position);
if(Q2==NULL){
printf("未找到第 %d 结点",position);
printf("添加失败failure\n");
return SQ;
}
//3.找到插入位置的前一个结点
DOUBLELINKLIST *Q1=Q2->prior;
//4.模拟插入的节点
DOUBLELINKLIST *P=(DOUBLELINKLIST *)malloc(sizeof(DOUBLELINKLIST));
P->data=insterData;
P->next=NULL;
P->prior=NULL;
//5.操作指针,将P插入链表中
//5.1.把P的next指针指向Q2
P->next=Q2;
//5.2.把Q2的priop指针指向P
Q2->prior=P;
//5.3.把P的prior指针指向Q1
P->prior=Q1;
//5.4.把Q1的next指针指向P
Q1->next=P;
printf("添加成功\n");
return SQ;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "DoubleLinkList.h"
int main(int argc, const char * argv[]) {
//向双向链表中添加数据
printf("向双向链表中添加数据\n");
DOUBLELINKLIST *insertList=createDoubleLinkList();
showDoubleLinkList(insertList);
DOUBLELINKLIST *insertSuccessList= insterDoubleLinkListByPosition(insertList,7,77);
showDoubleLinkList(insertSuccessList);
printf("\n");
}
打印结果:
向双向链表中添加数据
list=[-1,1,2,3,4,5,6,7,8,9,10]
添加成功
list=[-1,1,2,3,4,5,6,77,7,8,9,10]
7.删除双向列表指定位置的的结点
在DoubleLinkList.h写出方法声明
#include "DoubleCs.c"
/*
删除双向列表指定位置的的结点
*/
DOUBLELINKLIST * deleteDoubleLinkListByPosition();
在DoubleLinkList.c中实现此方法
#include "DoubleLinkList.h"
#include <stdlib.h>
#include <stdio.h>
/*
删除双向列表指定位置的的结点
*/
DOUBLELINKLIST * deleteDoubleLinkListByPosition(DOUBLELINKLIST *SQ,int position){
//1.链表的头结点赋给临时结点
DOUBLELINKLIST *temp;
temp=SQ;
//2.查找到指定位置的节点
DOUBLELINKLIST *deleteNode=findDoubleLinkListByPosition(temp, position);
if(deleteNode==NULL){
printf("未找到第 %d 结点\n",position);
printf("删除失败failure\n");
return SQ;
}
//3.获取删除结点的前一个结点
DOUBLELINKLIST *Q1=deleteNode->prior;
//4.获取删除节点的后一个结点
DOUBLELINKLIST *Q3=deleteNode->next;
//5.操作指针,删除deleteNode结点
//5.1.将Q1的next指针指向deleteNode的后一个结点
Q1->next=deleteNode->next;
//5.2.将Q3的prior的指针指向Q1
if(Q3==NULL){
//表示删除的是最后一个节点,则不用操作Q3的pripr指针
}else{
Q3->prior=deleteNode->prior;
}
//6.释放删除的结点deleteNode
free(deleteNode);
printf("删除成功success\n");
return SQ;
}
在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "DoubleLinkList.h"
int main(int argc, const char * argv[]) {
//删除双向链表指定位置的结点
printf("删除双向链表指定位置的结点\n");
DOUBLELINKLIST *deleteList=createDoubleLinkList();
showDoubleLinkList(deleteList);
DOUBLELINKLIST *deleteSuccessList= deleteDoubleLinkListByPosition(deleteList,6);
showDoubleLinkList(deleteSuccessList);
printf("\n");
}
打印结果:
删除双向链表指定位置的结点
list=[-1,1,2,3,4,5,6,7,8,9,10]
删除成功success
list=[-1,1,2,3,4,5,7,8,9,10]
这是对双向链表的基本操作,如有改善的地方,请大家提出,互相学习和进步.如果有好的关于数据结构与算法的书籍,还往大家推荐!