带头结点的循环双向链表
代码如下:
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef union DataType
{
int num; //用头结点的数据域存放结点个数
ElemType value;
}DataType;
typedef struct CDLNode //定义结点结构体
{
DataType data;
struct CDLNode *prior;
struct CDLNode *next;
}CDLNode,*CDLinkList;
void CDLinkList_Init(CDLinkList head)//初始化
{
assert(head!=NULL);
if(head==NULL) exit(0);
head->next =head;
head->prior =head;
head->data.num =0;
}
static CDLinkList CDLinkList_FindPrior(CDLinkList head,int pos) //找pos的前驱结点
{
CDLinkList p=head;
while(pos>0)
{
p=p->next ;
pos--;
}
return p;
}
CDLinkList Apply_Node(ElemType val) //申请新结点
{
CDLinkList p=(CDLinkList)malloc(sizeof(CDLNode));
assert (p!=NULL);
if(p == NULL) return NULL;
p->next =NULL;
p->data.value =val;
p ->prior =NULL;
return p;
}
bool CDLinkList_Insert_Tail(CDLinkList head,ElemType val) //尾插
{
assert(head!=NULL);
if(head==NULL) exit(0);
CDLinkList p=Apply_Node(val);
if(p==NULL) exit(0);
p->prior =head->prior ;
p->next =head;
p->prior ->next =p;
head->prior =p;
head->data .num ++;
return true;
}
bool CDLinkList_Insert_Pos(CDLinkList head,ElemType val,int pos)//按位置插入
{
assert(head!=NULL);
if(head==NULL) exit(0);
if(pos<0||pos>head->data .num ) return false;
if(pos==head->data .num)
{
CDLinkList_Insert_Tail(head,val);
}
else
{
CDLinkList s=Apply_Node(val);
if(s==NULL) exit(0);
CDLinkList p=CDLinkList_FindPrior(head,pos);//pos前驱
if(p->next !=NULL)
{
p->next ->prior =s;
s->next=p->next;
p->next =s;
s->prior =p;
head->data .num ++;
}
}
return true;
}
bool CDLinkList_Insert_Head(CDLinkList head,ElemType val) //头插
{
return CDLinkList_Insert_Pos (head,val,0);
}
bool CDLinkList_Delete_Tail(CDLinkList head)//尾删
{
assert(head!=NULL);
if(head==NULL) exit(0);
CDLinkList p=head->prior ;
p->prior->next =head;
head->prior =p->prior ;
free(p);
head->data .num --;
return true;
}
bool CDLinkList_Delete_Head(CDLinkList head)//头删
{
assert(head!=NULL);
if(head==NULL) exit(0);
CDLinkList p=head->next ;
head->next =p->next ;
p->next ->prior =head;
free(p);
head->data .num --;
return true;
}
bool CDLinkList_Delete_Pos(CDLinkList head,int pos)//按位置删
{
assert(head!=NULL);
if(head==NULL) exit(0);
if(pos<0||pos>head->data .num -1) return false;
if(pos==0)
{
CDLinkList_Delete_Head(head);
}
else if(pos==head->data .num -1)
{
CDLinkList_Delete_Tail (head);
}
else
{
CDLinkList p=CDLinkList_FindPrior(head,pos)->next ;//pos结点
p->next->prior =p->prior;
p->prior ->next =p->next ;
free(p);
head->data .num --;
}
return true;
}
int CDLinkList_Clear(CDLinkList head) //清除
{
assert(head!=NULL);
if(head==NULL) exit(0);
while(head->data .num )
{
if(!CDLinkList_Delete_Tail(head))
{
return false;
}
}
return true;
}
void Show(CDLinkList head) //输出链表
{
assert(head!=NULL);
if(head==NULL) exit(0);
CDLinkList p=head->next ;
while(p!=head)
{
printf("%d ",p->data .value );
p=p->next ;
}
printf("\n");
}
int main()
{
CDLNode head;
CDLinkList_Init(&head);
for(int i=1;i<8;i++)
{
CDLinkList_Insert_Tail(&head,i);//尾插
}
Show(&head);
CDLinkList_Insert_Pos(&head,21,1);//按位置插
Show(&head);
CDLinkList_Insert_Head (&head,90);//头插
Show(&head);
CDLinkList_Delete_Tail(&head);//尾删
Show(&head);
CDLinkList_Delete_Head(&head);//头删
Show(&head);
CDLinkList_Delete_Pos(&head,3);//按位删
Show(&head);
CDLinkList_Clear(&head);//清除
Show(&head);
return 0;
}
运行结果如下: