//10.5 双向链表基本运算
#include <stdio.h>
#include <stdlib.h>
typedef struct dlnode
{
char data; //data 为节点的数据信息
struct dlnode *prior; //prior 为指向前驱结点的指针
struct dlnode *next; //next 为指向后继节点的指针
}DLNode; //双向链表节点类型
DLNode * CreateDlinkList() //建立带头节点的双向循环链表
{
DLNode *head, *s;
char x;
head = (DLNode *)malloc(sizeof(DLNode)); //先生成仅含头系欸但的空双向循环链表
head->prior = head;
head->next = head;
printf("Input any char string:\n");
scanf("%c", &x); //读入节点数据
while (x != '\n')
{
s = (DLNode *)malloc(sizeof(DLNode)); //生成待插入节点的存储空间
s->data = x; //将读入的数据赋值给待插入节点*s
s->prior = head; //新插入的节点*s其前驱结点为头节点*head
s->next = head->next; //插入后*s的后继节点为头节点*head原来的后继节点
head->next->prior = s; //头节点的原后继节点其前驱结点为*s
head->next = s; //头节点此时新的后继节点为*s
scanf("%c", &x);
}
return head; //返回头指针
}
DLNode *Get_DLinkList(DLNode *head, int i)
{ //在单链表head中按序号查找第i个节点
DLNode *p = head;
int j = 0;
while (p->next != head && j < i) //由第一个数据节点开始查找,j 用于计数
{
p = p->next;
j++;
}
if (p->next != head)
{
return p; //找到则返回指向i 节点的指针值
}
else
{
return NULL; //找不到则返回空值
}
}
void Insert_DLinkList(DLNode *head, int i, char x)
{ //在单链表head 的第i 个位置上插入值为x 的元素
DLNode *p, *s;
p = Get_DLinkList(head, i - 1); //查找第i-1 个节点
if (p == NULL)
{
printf("Error!\n"); //第i-1 个节点位置不存在而无法插入
}
else
{
s = (DLNode *)malloc(sizeof(DLNode)); //申请节点空间
s->data = x;
s->prior = p; //新插入的节点*s其前驱节点为*p
s->next = p->next; //插入后*s 的后继节点为*p 原来的后继节点
p->next->prior = s; //*p 原后继节点此时的前驱结点为*s
p->next = s; //插入后*p 的后继节点为*s
}
}
void Del_DLinkList(DLNode *head, int i)
{ //删除单链表head 上的第i个节点
DLNode *p;
p = Get_DLinkList(head, i); //查找第i 个节点
if (p == NULL)
{
printf("第i 个数据节点不存在!\n"); //待删节点不存在
}
else
{
p->prior->next = p->next; //待删节点*p 的前驱结点其后继指针指向*p 的后继节点
p->next->prior = p->prior; //待删节点*p 的后继节点其前驱指针指向*p 的前驱结点
free(p); //系统回收*p 节点的存储空间
}
}
void print1(DLNode *h) //后向输出双向循环链表
{
DLNode *p;
p = h->next;
while (p != h)
{
printf("%c, ", p->data);
p = p->next;
}
printf("\n");
}
void print2(DLNode *h) //前向输出双向循环链表
{
DLNode *p;
p = h->prior;
while (p != h)
{
printf("%c, ", p->data);
p = p->prior;
}
printf("\n");
}
int main()
{
DLNode *h, *p;
int i;
char x;
h = CreateDlinkList(); //建立带头节点的双向循环链表
printf("Output list for next\n");
print1(h); //后向输出双向循环链表
printf("Output list for prior\n");
print2(h); //前向输出双向循环链表
printf("Input order and search to element:\n");
scanf("%d", &i); //输入要查找元素的序号
p = Get_DLinkList(h, i); //按序号在顺序表中查找
if (p != NULL)
{
printf("Element is %c\n", p->data); //找到则输出该元素的值
}
else
{
printf("Search fail!\n"); //未找到
}
printf("Insert a element, Input site and value of element:\n");
scanf("%d %c", &i, &x); //输入要插入元素的位置值i 和元素值x
Insert_DLinkList(h, i, x); //在双向循环链表中插入该元素
print1(h); //输出双向循环链表节点信息
printf("Delete a element, Input site of element:\n");
scanf("%d", &i); //输入要删除元素的位置值i
Del_DLinkList(h, i); //在单链表中删除该位置上的元素
print1(h); //输出双向循环链表节点信息
printf("Press any key to quit.");
getchar(); //接收回车键
getchar();
return 0;
}
10.5 双向链表基本运算
最新推荐文章于 2023-11-02 20:29:36 发布