#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int ElemType;
typedef struct SLTNode//是一个带头结点的循环双链表
{
struct SLTNode* next;
struct SLTNode* prev;
ElemType data;
}SLTNode;//因为带了头结点,头指针始终指向头结点(哨兵位),所以带头结点的双链表除了初始化头结点,不需要用二级指针
//创建结点
SLTNode* BuyListNode(ElemType elem)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
if(newnode == NULL)
{
exit(-1);
}
newnode->data = elem;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
//初始化
SLTNode* ListInit()//这里使用返回值的方法,也可以使用二级指针来初始化
{
SLTNode* phead = BuyListNode(0);
phead->next = phead;
phead->prev = phead;
return phead;
}
//打印
void SLTPrint(SLTNode* phead)
{
assert(phead);
SLTNode* cur = phead->next;//哨兵位是不用打印的,因为它没有存放值
while(cur != phead)
{
printf("%d->",cur->data);
cur = cur->next;
}
printf("NULL\n");
}
//头插
void SLTPushFront(SLTNode* phead,ElemType elem)
{
assert(phead);
SLTNode* newnode = BuyListNode(elem);
SLTNode* cur = phead->next;
phead->next = newnode;
newnode->prev = phead;
newnode->next = cur;
cur->prev = newnode;
}
//头删
void SLTPopFront(SLTNode* phead)
{
assert(phead);
if(phead->next == phead)
{
printf("无有效值可以删除\n");
return;
}
SLTNode* freeone = phead->next;//记录下要销毁的结点
SLTNode* cur = phead->next->next;
phead->next = cur;
cur->prev = phead;
free(freeone);
}
//尾插
void SLTPushBack(SLTNode* phead,ElemType elem)
{
assert(phead);
SLTNode* tail = phead->prev;
SLTNode* newnode = BuyListNode(elem);
tail->next = newnode;
newnode->prev = tail;
phead->prev = newnode;
newnode->next = phead;
}
//尾删
void SLTPopBack(SLTNode* phead)
{
assert(phead);
if(phead->next == phead)
{
printf("无有效值可以删除\n");
return;
}
SLTNode* tail = phead->prev;
SLTNode* cur = tail->prev;
cur->next = phead;
phead->prev = cur;
free(tail);
}
//查找
void SLTFind(SLTNode* phead,ElemType pos)
{
assert(phead);
SLTNode* cur = phead->next;
if(cur == phead)
{
printf("该表无有效值\n");
return;
}
while(cur != phead)
{
if(cur->data == pos)
{
printf("该值的地址是%p",cur);
return;
}
else
{
cur = cur->next;
}
}
printf("找不到\n");
}
//任意结点后的插入
void SLTInsert(SLTNode* phead,ElemType pos,ElemType elem)
{
SLTNode* cur = phead;
while(cur->next != phead)
{
if(cur->data == pos)
{
SLTNode* newnode = BuyListNode(elem);
SLTNode* curnext = cur->next;
newnode->prev = cur;
cur->next = newnode;
newnode->next = curnext;
curnext->prev = newnode;
}
else
{
printf("找不到该结点\n");
return;
}
}
}
//任意结点的删除
void SLTDelete(SLTNode* phead,ElemType pos)
{
assert(phead);
SLTNode* cur = phead->next;
while(cur != phead)
{
if(cur->data == pos)
{
SLTNode* curprev = cur->prev;
SLTNode* curnext = cur->next;
free(cur);
curprev->next = curnext;
curnext->prev = curprev;
return;
}
}
}
int main()
{
ElemType elem;
ElemType pos;
SLTNode* phead = ListInit();
int status;
printf("请选择要进行的操作:\n");
printf("1、头插 2、头删 3、尾插 4、尾删\n");
printf("5、查找 6、插入 7、删除 8、打印\n");
while(1)
{
scanf("%d",&status);
switch(status)
{
case 1:
printf("请输入要插入的值:\n");
scanf("%d",&elem);
SLTPushFront(phead,elem);
break;
case 2:
SLTPopFront(phead);
break;
case 3:
printf("请输入要插入的值:\n");
scanf("%d",&elem);
SLTPushBack(phead,elem);
break;
case 4:
SLTPopBack(phead);
break;
case 5:
printf("请输入要查找的值:\n");
scanf("%d",&pos);
SLTFind(phead,pos);
break;
case 6:
printf("请输入要插入的位置和值:\n");
scanf("%d %d",&pos,&elem);
SLTInsert(phead,pos,elem);
break;
case 7:
printf("请输入要删除的结点:\n");
scanf("%d",&pos);
SLTDelete(phead,pos);
break;
case 8:
SLTPrint(phead);
break;
default:
printf("error!\n");
exit(-1);
}
}
return 0;
}
带头循环双链表
最新推荐文章于 2024-07-25 11:43:17 发布