// 双链表
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int ElemType;
/*构建双链表结构体类型*/
typedef struct DNode
{
ElemType data; // 数据域
struct DNode* prior, * next; // 前驱和后继指针
}DNode;
/*函数声明*/
// 双链表初始化
DNode* initList();
// 输出
void outputList(DNode* dp);
// 通过下标获取结点值
ElemType getElemByIndex(DNode* dp, int index);
// 通过下标获取结点值 getIndexByElem
int getIndexByElem(DNode* dp, ElemType e);
// 插入值
int insertElem(DNode* dp,int index, ElemType e);
// 删除值
ElemType delElemByIndex(DNode* dp, int index);
// 求表长
int lenList(DNode* dp);
int main(int argc, char** argv)
{
// code
int a;
int index; // 插入/删除的下标
ElemType e; // 要插入/删除的元素
DNode* dp = NULL;
// 初始化操作
while (1)
{
printf("\n");
printf("\n**************************\n");
printf("==========================\n");
printf("1. 创建双链表(尾插法)\n");
printf("2. 查看双链表\n");
printf("3. 按下标查找结点值\n");
printf("4. 按值查找下标\n");
printf("5. 插入结点操作\n");
printf("6. 删除结点操作\n");
printf("7. 求表长操作\n");
printf("0. 退出\n");
printf("请选择操作:");
scanf("%d", &a);
printf("\n==========================\n");
printf("**************************\n");
if (a == 0)
{
printf("=====程序结束=====\n");
break;
}
switch (a)
{
case 1:
dp = initList();
break;
case 2:
outputList(dp);
break;
case 3:
printf("请输入下标值:");
scanf("%d", &index);
e = getElemByIndex(dp, index);
if (e)
{
printf("下标为%d的值为:%d\n", index, e);
}
else
{
printf("操作失败!!!");
}
break;
case 4:
printf("请输入查找的值:");
scanf("%d", &e);
index = getIndexByElem(dp, e);
if (index != -1)
{
printf("值为%d的下标为:%d\n", e, index);
}
else
{
printf("操作失败!!!");
}
break;
case 5:
printf("请输入插入的下标:");
scanf("%d", &index);
printf("请输入插入的值:");
scanf("%d", &e);
index = insertElem(dp, index, e);
if (!index)
{
printf("操作失败!!!");
}
break;
case 6:
printf("请输入删除的下标:");
scanf("%d", &index);
e = delElemByIndex(dp, index);
printf("删除的值为:%d", e);
break;
case 7:
index = lenList(dp);
printf("双链表的表长为:%d\n", index);
break;
default:
break;
}
}
system("pause");
return 0;
}
DNode* initList()
{
int x;
DNode* headp = (DNode*)malloc(sizeof(DNode)); // 创建一个头结点
DNode* tailp = headp; // 表尾结点,默认指向头结点
DNode* tempp = NULL; // 用于临时申请系统空间
printf("请输入创建单链表的值(以回车间隔):\n");
for (int i = 0; i < 5; i++)
{
scanf("%d", &x); // 输入新结点值
tempp = (DNode*)malloc(sizeof(DNode)); // 为新结点申请系统空间
tempp->data = x; // 新结点的值
tailp->next = tempp; // 上一结点的后继指向新结点
tempp->prior = tailp; // 新结点的前驱指向上一结点
tailp = tempp; // 指向新结点的表尾
}
tailp->next = NULL;
return headp;
}
void outputList(DNode* dp)
{
DNode* tempp = dp->next; // 将头结点的后继赋给tempp
printf("单链表为:");
while (tempp)
{
printf("%d ", tempp->data);
tempp = tempp->next;
}
}
ElemType getElemByIndex(DNode* dp, int index)
{
DNode* tempp = dp->next; // 将头结点的后继赋给tempp
if (index < 0)
{
return NULL; // 下标无效
}
for (int i = 1; i <= index; i++) // 下标大于0时
{
if (tempp)
{
tempp = tempp->next;
}
}
if (tempp)
{
return tempp->data;
}
else
{
return NULL;
}
}
int getIndexByElem(DNode* dp, ElemType e)
{
DNode* tempp = dp->next; // z指向头结点de后继
int len = lenList(dp); // 获取链表的表长
int i;
for (i = 0; i < len; i++)
{
if (tempp && tempp->data == e)
{
return i;
break;
}
tempp = tempp->next;
}
return -1;
}
int insertElem(DNode* dp, int index, ElemType e)
{
DNode* tempp = dp; //
if (index < 0 || index > lenList(dp))
{
return 0; // 下标无效
}
for (int i = 0; i < index; i++)
{
tempp = tempp->next; // 获取插入结点位置
}
DNode* newp = (DNode*)malloc(sizeof(DNode)); // 申请新的系统空间
newp->data = e; // 插入的结点值
/*// 后插法*/
// 新结点与后继结点相连
newp->next = tempp->next;
if (tempp->next)
{
tempp->next->prior = newp; // 当插在末尾时,不需要此行
}
// 前驱结点与新结点相连
tempp->next = newp;
newp->prior = tempp;
//DNode* priorp = tempp->prior; // 插入结点位置的前驱结点
插入结点位置的前驱结点与新结点相连
//priorp->next = newp;
//newp->prior = priorp;
新结点与后继结点相连
//newp->next = tempp;
//tempp->prior = newp;
return 1;
}
ElemType delElemByIndex(DNode* dp, int index)
{
DNode* tempp = dp->next;
if (index < 0 || index > lenList(dp) - 1)
{
return NULL; // 下标无效
}
for (int i = 0; i < index; i++)
{
tempp = tempp->next;
}
DNode* delp = tempp; // 要被删除的结点
ElemType delElem = delp->data; // 保留要被删除的值
DNode* priorp = tempp->prior; // 被删除结点的前驱结点
DNode* nextp = tempp->next; // 被删除结点的后继结点
// 前驱和后继相连
priorp->next = nextp;
if (tempp->next)
{
nextp->prior = priorp; // 删除最后一个时,不需要执行
}
free(delp); // 释放空间
return delElem;
}
int lenList(DNode* dp)
{
DNode* tempp = dp->next;
int i = 0;
while (tempp)
{
tempp = tempp->next;
i++;
}
return i;
}
双链表-C语言
最新推荐文章于 2023-05-08 13:03:05 发布