内容:数据结构第二章线性链表C语言代码实现
参考书:数据结构严书,高一凡数据结构与算法
测试软件:Visual Studio 2017
c1.h:
#ifndef __C1_H
//#define __C1_H
//c1.h(头文件名)
#include <string.h> //字符串函数头文件
#include <ctype.h> //字符函数头文件
#include <malloc.h> //malloc()等
#include <limits.h> //INT_MAX等
#include <stdio.h> //标准输入输出头文件,包括EOF( = ^Z 或F6),NULL等
#include <stdlib.h> //atoi(), exit()
#include <io.h> //eof()
#include <math.h> //数学函数头文件,包括floor(), ceil(), abs()等
#include <sys/timeb.h> //ftime()
#include <stdarg.h> //提供宏va_start, va_arg, va_end,用于存取变长参数表
//函数结果状态代码。在严书第十页
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
//#define INFESIBLE -1
//#define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; //Status是函数的;类型其值是函数结果状态代码,如OK等
typedef int Boolean; //Boolean是布尔类型,其值是TRUE或FALSE,第7、8、9章用到
typedef int ElemType;
#endif // !__C1_H
#pragma once
c2-2.h:
#ifndef C2-2_H
#include "c1.h"
struct LNode
{
ElemType data;
LNode * next;
};
typedef LNode * LinkList;
#endif // !C2-2_H
#pragma once
bo2-2.h:
#ifndef BO2-2_H
#include "c1.h"
#include "c2-2.h"
void InitList(LinkList &L) //构造一个空的线性表L
{
L = (LinkList)malloc(sizeof(LNode));
if (!L)
exit(OVERFLOW);
L->next = NULL;
}
void DestroyList(LinkList &L) //销毁线性表
{
LinkList q;
while (L)
{
q = L->next;
free(L);
L = q;
}
}
void ClearList(LinkList L) //不改变L
{
LinkList p = L->next;
L->next = NULL;
DestroyList(p);
}
Status ListEmpty(LinkList L)
{
if (L->next)
return FALSE;
else
return TRUE;
}
int ListLength(LinkList L) //返回L中的元素个数
{
int i = 0;
LinkList p = L->next;
while (p)
{
i++;
p = p->next;
}
return i;
}
Status GetElem(LinkList L, int i, ElemType &e) //
{
int j = 1;
LinkList p = L->next;
while (p && j < i)
{
j++;
p = p->next;
}
if (!p || j > i)
return ERROR;
e = p->data;
return OK;
}
int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
int i = 0;
LinkList p = L->next;
while (p)
{
i++;
if (compare(p->data, e))
return i;
p = p->next;
}
return 0;
}
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e) //找cur_e的前驱
{
LinkList q, p = L->next;
while (p && p->next)
{
q = p->next;
if (q->data == cur_e)
{
pre_e = p->data;
return OK;
}
p = q;
}
return ERROR;
}
Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e)
{
LinkList p = L->next;
while (p && p->next)
{
if (p->data == cur_e)
{
next_e = p->next->data;
return OK;
}
p = p->next;
}
return ERROR;
}
Status ListInsert(LinkList L, int i, ElemType e) //在i之前的位置插入e
{
int j = 0;
LinkList s, p = L;
while (p && j < i-1)
{
j++;
p = p->next;
}
if (!p || j > i - 1)
return ERROR;
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
Status ListDelete(LinkList L, int i, ElemType &e) //删除第i个元素
{
int j = 0;
LinkList q, p = L;
while (p->next && j < i - 1)
{
j++;
p = p->next;
}
if (!p->next || j > i - 1)
return ERROR;
q = p->next; //q指向待删除结点
p->next = q->next; //待删除结点的前驱指向待删除结点的后继
e = q->data; //待删除结点的值赋给e
free(q); //释放待删结点
return OK;
}
void ListTraverse(LinkList L, void(*visit)(ElemType)) //依次对L的每个元素调用visit函数
{
LinkList p = L->next;
while (p)
{
visit(p->data);
p = p->next;
}
printf("\n");
}
#endif // !BO2-2_H
#pragma once
func2-2.h:
#ifndef FUNC2-2_H
//#define FUNC2-2_H
#include "c1.h"
#include "c2-1.h"
#include "bo2-1.h"
Status equal(ElemType c1, ElemType c2) //判断是否相等
{
if (c1 == c2)
return TRUE;
else
return FALSE;
}
int comp(ElemType a, ElemType b)
{
if (a == b)
return 0;
else
return (a-b)/abs(a-b); //如1-2 / |1-2| = -1
}
void print(ElemType c)
{
printf(" %d ", c);
}
void print1(ElemType &c)
{
printf(" %d ", c);
}
void print2(ElemType c)
{
printf(" %c ", c);
}
#endif // !FUNC2-2_H
#pragma once
func2-3.h:
#ifndef FUNC2-3_H
#include "c1.h"
#include "c2-2.h"
#include "bo2-2.h"
#include "func2-2.h"
void main()
{
LinkList L;
ElemType e, e0;
Status i;
int j, k;
InitList(L);
for (j = 1; j <= 5; j++)
i = ListInsert(L, 1, j);
printf("在L的表头依次插入1~5后,L = ");
ListTraverse(L, print);
i = ListEmpty(L);
printf("L是否空?i = %d(1:是 0:否),表L的长度 = %d\n", i, ListLength(L));
ClearList(L);
printf("清空L后,L = ");
ListTraverse(L, print);
i = ListEmpty(L);
printf("L是否空?i = %d(1:是 0:否),表L的长度 = %d\n", i, ListLength(L));
for (j = 1; j <= 10; j++)
i = ListInsert(L, j, j);
printf("在L的表头依次插入1~10后,L = ");
ListTraverse(L, print);
for (j = 0; j <= 1; j++)
{
#ifdef SLL //仅用于静态链表
k = LocateElem(L, j);
if (k)
printf("值为%d的元素的位序为%d\n", j, k);
#else
k = LocateElem(L, j, equal);
if (k)
printf("值为%d的元素的位序为%d\n", k, j);
#endif // SLL
else
printf("没有值为%d的元素,", j);
}
for (j = 1; j <= 2; j++) //测试前两个数据
{
GetElem(L, j, e0);
i = PriorElem(L, e0, e);
if (i == ERROR)
printf("元素%d无前驱,", e0);
else
printf("元素%d的前驱为%d\n", e0, e);
}
for (j = ListLength(L) - 1; j <= ListLength(L); j++) //最后两个数据
{
GetElem(L, j, e0);
i = NextElem(L, e0, e);
if (i == ERROR)
printf("元素%d无后继\n", e0);
else
printf("元素%d的后继为%d,", e0, e);
}
k = ListLength(L);
for (j = k + 1; j >= k; j--)
{
i = ListDelete(L, j, e); //删除第j个元素
if (i == ERROR)
printf("删除第%d个元素失败(不存在此元素)。", j);
else
printf("删除第%d个元素成功,其值为%d\n", j, e);
}
printf("依次输出L的元素:");
ListTraverse(L, print);
DestroyList(L);
#ifndef SLL //仅用于链表
printf("销毁L后,L = %u\n", L);
#endif // !SLL //仅用于链表
}
#endif // !FUNC2-3_H
#pragma once
main2-2.cpp:
// 线性链表.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "c1.h"
#include "c2-2.h"
#include "bo2-2.h"
#include "func2-2.h"
#include "func2-3.h"