双向循环链表的增 删 查 输出
上一次介绍了单向循环链表,这一次介绍双向循环链表。
链表的特点
顾名思义,双向循环链表的结点中有两个指针域,一个指向直接后继,一个指向直接前驱。
链表的描述
描述: 数据域+两个指针域
typedef int datatype;
typedef struct node {
datatype data;
struct node * prior;
struct node * next;
}dlinklist, *dlinklist_t;
基本操作
创建空链表
用malloc动态申请空间
dlinklist_t createDLinkList()
{
//1.申请空间
dlinklist_t H = (dlinklist_t)malloc(sizeof(dlinklist));
if(NULL == H)
{
printf("malloc head node fail\n");
return NULL;
}
//2.赋值:数据无效,两个指针都指向自己
H->data = -1;
H->prior = H;
H->next = H;
return H;
}
第一种插入方式:头插
头插,新结点永远插入第一项(头结点不是第一项,头结点后面才是第一项)
代码的书写顺序可以有很多种,只要逻辑通顺即可。
int headInsert(dlinklist_t H, datatype x)
{
//1.封装结点
dlinklist_t pnew = (dlinklist_t)malloc(sizeof(dlinklist));
if(NULL == pnew)
{
printf("malloc new node fail\n");
return -1;
}
pnew->data = x;
//2.接入头结点后面
pnew->prior = H;
pnew->next = H->next;
H->next->prior = pnew;
H->next = pnew;
return 0;
}
输出链表
void showDLinkList(dlinklist_t H)
{
dclinkPtr p = H->next;
while(p != H)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
查
单链表中,取第i个元素必须从头结点出发寻找。
按位置查找,查找第pos项元素,返回其地址
dlinklist_t searchPos(dlinklist_t H, int pos)
{
int count = -1;
dlinklist_t p = H;
if(pos < 0)
{
printf("位置不合法:pos < 0\n");
return NULL;
}
while(count < pos)
{
p = p->next;
count++;
if(p == H)
{
printf("位置不合法:pos > 表长\n");
return NULL;
}
}
return p;
}
第二种插入方式:任意位置插入新结点
要利用上面的查找函数searchPos()
int insertDLinkList(dlinklist_t H, int pos, datatype x)
{
dlinklist_t pnew = NULL;//新增结点
dlinklist_t p = searchPos(H, pos);//找位置
if(NULL == p) //位置合法不?
return -1;
//2.封装新结点
pnew = (dlinklist_t)malloc(sizeof(dlinklist));
if(NULL == pnew)
{
printf("malloc newnode fail\n");
return -1;
}
pnew->data = x;
//3.插入新增结点
pnew->prior = p->prior;
pnew->next = p;
p->prior->next = pnew;
p->prior = pnew;
return 0;
}
删
删除结点
int deleteDLinkList(dlinklist_t H, int pos, datatype *x)
{
//1.找位置
dlinklist_t p = searchPos(H, pos);
if(NULL == p)
return -1;
//2.删除
p->prior->next = p->next;
p->next->prior = p->prior;
//3.释放该结点空间
*x = p->data;
free(p);
p = NULL;
return 0;
}
测试
dlinklist_t H = createDLinkList();
if(NULL == H)
{
printf("createDLinkList fail\n");
return -1;
}
headInsert(H, 4);
headInsert(H, 3);
headInsert(H, 2);
headInsert(H, 1);
showDLinkList(H);
int pos = 2;
dlinklist_t p = searchPos(H, pos);
printf("下标%d = %d\n", pos, p->data);
insertDLinkList(H, 2, 666);
insertDLinkList(H, 2, 777);
insertDLinkList(H, 2, 888);
printf("insert: ");
showDLinkList(H);
datatype x;
deleteDLinkList(H, 2, &x);
deleteDLinkList(H, 2, &x);
deleteDLinkList(H, 2, &x);
printf("delete: ");
showDLinkList(H);