王道数据结构实践代码----单链表的实现(C语言版)
前言
日期:2021年8月28日 书籍:王道2021年数据结构考研复习指导 代码内容:实现双链表的实现,包括初始化,插入新元素,删除新元素,输出,查询
代码难点
1.双链表插入、删除的操作
上图操作的语句顺序不是唯一的,但也不是任意的,①和②两步必须在④步之前,否则p的后继结点的指针就会丢掉,导致插入失败。 为了加深理解,读者可以在纸上画出示意图。 若问题改成要求在结点p之前插入结点s,请读者思考具体的操作步骤。 此处①②无顺序要求 若问题改成要求删除结点q的前驱结点*p,请读者思考具体的操作步骤。
代码展示
双链表结构体定义
#include <stdio.h>
#include <stdlib.h>
#define bool char
#define false 0
#define true 1
typedef int ElemType;
typedef struct DNode
{
ElemType data;
struct DNode *next;
struct DNode *prior;
}DNode,*DLinkList;
双链表初始化函数
DLinkList DLinkListInit()
{
DLinkList L = (DLinkList)malloc(sizeof(DLinkList));
L->next = NULL;
L->prior = NULL;
return L;
}
双链表的插入操作
DNode* CreateNewDNode(ElemType data)
{
DNode* newNode = (DNode*)malloc(sizeof(DNode));
if(!newNode)
{
printf("分配空间失败,请检查内存!\n");
return NULL;
}
newNode->data = data;
newNode->next = NULL;
newNode->prior = NULL;
return newNode;
}
DNode* GetElem(DLinkList L, int i)
{
if(L->next == NULL) {printf("这是空表!"); return L;}
DNode* p = L->next;
if(i < 1)
{
p = L;
return p;
}
while (p->next != NULL && i != 1)
{
p = p->next;
i--;
}
if(i != 1)
printf("没有这个节点,返回链表的最后一位.\n");
return p;
}
DNode* LocateElem(DLinkList L,ElemType e)
{
if(L->next == NULL) {printf("这是空表!"); return L;}
DNode* p = L->next;
while (p->next != NULL && p->data != e)
{
p = p->next;
}
if(p->data != e)
printf("没有这个节点,返回链表的最后一位.");
return p;
}
bool DLinkListInsert(DLinkList L,int i,ElemType e)
{
if(i < 1)
{
printf("输入出错!");
return 0;
}
DNode* s = CreateNewDNode(e);
if(s == NULL) return 0;
DNode* p = GetElem(L,i-1);
s->next = p->next;
if(p->next != NULL)
p->next->prior = s;
s->prior = p;
p->next = s;
return 1;
}
双链表的遍历
int PrintDLinkList(DLinkList L)
{
if (L == NULL)
{
printf("该链表不存在\n");
return 0;
}
if(L->next == NULL)
{
printf("这是空表!没有需要打印的元素");
return 0;
}
DNode* p = L->next;
int i = 0;
while (p!= NULL)
{
i++;
printf("第%d个元素的内容值为:%d\n",i,p->data);
p = p->next;
}
printf("打印结束,共%d个链表结点.\n",i);
return 0;
}
双链表的删除操作
bool DLinkLisDelete(DLinkList L,int i)
{
if(L->next == NULL)
{
printf("表空,无删除元素\n");
return false;
}
DNode* p = GetElem(L,i-1);
if(p == NULL) return false;
DNode* q = p->next;
if(q == NULL) return false;
p->next = q->next;
if(q->next != NULL)
q->next->prior = p;
free(q);
return true;
}
void DestoryList(DLinkList L)
{
while (L->next != NULL)
{
DLinkLisDelete(L,1);
}
}
整体代码展示
#include <stdio.h>
#include <stdlib.h>
#define bool char
#define false 0
#define true 1
typedef int ElemType;
typedef struct DNode
{
ElemType data;
struct DNode *next;
struct DNode *prior;
}DNode,*DLinkList;
DLinkList DLinkListInit()
{
DLinkList L = (DLinkList)malloc(sizeof(DLinkList));
L->next = NULL;
L->prior = NULL;
return L;
}
DNode* CreateNewDNode(ElemType data)
{
DNode* newNode = (DNode*)malloc(sizeof(DNode));
if(!newNode)
{
printf("分配空间失败,请检查内存!\n");
return NULL;
}
newNode->data = data;
newNode->next = NULL;
newNode->prior = NULL;
return newNode;
}
DNode* GetElem(DLinkList L, int i)
{
if(L->next == NULL) {printf("这是空表!"); return L;}
DNode* p = L->next;
if(i < 1)
{
p = L;
return p;
}
while (p->next != NULL && i != 1)
{
p = p->next;
i--;
}
if(i != 1)
printf("没有这个节点,返回链表的最后一位.\n");
return p;
}
DNode* LocateElem(DLinkList L,ElemType e)
{
if(L->next == NULL) {printf("这是空表!"); return L;}
DNode* p = L->next;
while (p->next != NULL && p->data != e)
{
p = p->next;
}
if(p->data != e)
printf("没有这个节点,返回链表的最后一位.");
return p;
}
bool DLinkListInsert(DLinkList L,int i,ElemType e)
{
if(i < 1)
{
printf("输入出错!");
return 0;
}
DNode* s = CreateNewDNode(e);
if(s == NULL) return 0;
DNode* p = GetElem(L,i-1);
s->next = p->next;
if(p->next != NULL)
p->next->prior = s;
s->prior = p;
p->next = s;
return 1;
}
int PrintDLinkList(DLinkList L)
{
if (L == NULL)
{
printf("该链表不存在\n");
return 0;
}
if(L->next == NULL)
{
printf("这是空表!没有需要打印的元素");
return 0;
}
DNode* p = L->next;
int i = 0;
while (p!= NULL)
{
i++;
printf("第%d个元素的内容值为:%d\n",i,p->data);
p = p->next;
}
printf("打印结束,共%d个链表结点.\n",i);
return 0;
}
bool DLinkLisDelete(DLinkList L,int i)
{
if(L->next == NULL)
{
printf("表空,无删除元素\n");
return false;
}
DNode* p = GetElem(L,i-1);
if(p == NULL) return false;
DNode* q = p->next;
if(q == NULL) return false;
p->next = q->next;
if(q->next != NULL)
q->next->prior = p;
free(q);
return true;
}
void DestoryList(DLinkList L)
{
while (L->next != NULL)
{
DLinkLisDelete(L,1);
}
}
int main()
{
DLinkList L = NULL;
L = DLinkListInit();
DLinkListInsert(L,1,1);
DLinkListInsert(L,1,2);
DLinkListInsert(L,1,3);
DLinkListInsert(L,1,4);
DLinkListInsert(L,1,5);
DLinkListInsert(L,1,6);
DLinkListInsert(L,1,7);
DLinkListInsert(L,1,8);
DLinkListInsert(L,1,9);
DLinkListInsert(L,1,10);
DLinkListInsert(L,1,11);
DLinkListInsert(L,1,12);
PrintDLinkList(L);
DLinkListInsert(L,4,888);
DLinkListInsert(L,7,1022);
DLinkListInsert(L,9,963);
DLinkListInsert(L,11,8522);
DLinkListInsert(L,100,150);
DLinkListInsert(L,4,12000);
DLinkListInsert(L,8,17869);
PrintDLinkList(L);
DLinkLisDelete(L,8);
PrintDLinkList(L);
DestoryList(L);
free(L);
L = NULL;
PrintDLinkList(L);
return 0;
}
运行效果图
|