首先创建头文件list.h
#pragma once
typedef struct DNode
{
int data;
struct DNode *next;//后继指针
struct DNode *ptior;//前驱指针
}DNode,*DList;
//初始化
void InitList(DList plist);
//头插
bool Insert_head(DList plist,int val);
//尾插
bool Insert_tail(DList plist,int val);
在plist中查找关键字key,找到返回结点,失败返回NULL
DNode *Search(DList plist,int val);
//判空
bool IsEmpty(DList plist);
//删除plist中的第一个key
bool DeleteVal(DList plist,int key);
//显示数据
void Show(DList plist);
//清除数据
void Clear(DList plist);
//销毁
void Destroy(DList plist);
编写list.cpp文件
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"list.h"
//判断list是否为空
static void DeterPointNull(DList plist)
{
assert(plist!=NULL);
if(plist==NULL)
{
printf("It is error,please cheak\n");
exit(0);//直接结束当前进程
}
}
//初始化
void InitList(DList plist)
{
DeterPointNull(plist);
//将头结点的前驱和后继都设置为NULL
plist->next=NULL;//不循环,循环则指向自己
plist->ptior=NULL;
}
//头插
bool Insert_head(DList plist,int val)
{
DeterPointNull(plist);
//创建新结点
DNode *p=(DNode *)malloc(sizeof(DNode));
p->data=val;//给结点赋值
DNode *q=plist->next;
if(q!=NULL)//如果q不为空则在q前插入p结点
{
p->next=q;//将p的后继设置为q
q->ptior=p; //将q的前驱设置为p
}
plist->next=p;//将plist的next域设置为p
p->ptior=plist;//p的前驱设置为plist
return true;
}
//尾插
bool Insert_tail(DList plist,int val)
{
DeterPointNull(plist);
DNode *p=plist;
while(p->next!=NULL)//查找尾结点
{
p=p->next;
}
DNode *q=(DNode *)malloc(sizeof(DNode));//创建新结点
q->data=val;//赋值
//将q插入到p的后面
q->next=p->next;
p->next=q;
q->ptior=p;
return true;
}
//在plist中查找关键字key,找到返回下标,失败返回null
DNode *Search(DList plist,int val)
{
for(DNode *p=plist->next;p!=NULL;p=p->next)
{
if(p->data==val)
{
return p;
}
}
return NULL;
}
//判空
bool IsEmpty(DList plist)
{
return plist->next==NULL;
}
//删除plist中的第一个key
bool DeleteVal(DList plist,int key)
{
//查找第一个key值结点
DNode *p=Search(plist,key);
if(p==NULL)
{
return false;
}
//将p从列表中剔除
p->ptior->next=p->next;
if(p->next !=NULL)
{
p->next->ptior=p->ptior;
}
return true;
}
//获取数据长度
int GetLength(DList plist)
{
int count=0;
for(DNode *p=plist->next;p!=NULL;p=p->next)
{
count++;
}
return count;
}
//输出所有数据
void Show(DList plist)
{
DeterPointNull(plist);
for(DNode *p=plist->next;p!=NULL;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
//清空
void Clear(DList plist)
{
DeterPointNull(plist);
plist->next=NULL;
plist->ptior=NULL;
}
//销毁
void Destroy(DList plist)
{
DeterPointNull(plist);
DNode *p;
while(plist->next!=NULL)
{
p=plist->next;
plist->next=p->next;
free(p);
}
}
可自行创建主函数,编写测试用例进行测试使用。
小知识:
遍历链表的形式:
for(DNode *p=plist;p->next!=NULL;p=p->next)
需要修改链表结构(前驱)的操作,例如:插入、删除
for(DNode p=plist->next;p!=NULL;p=p->next)
只是遍历所有的数据结点,不需要修改链表结构,例如:查找,输出,获取长度/