为了找工作,现在有重新拿起了阔别已久的数据结构。《数据结构》严蔚敏C版、《大话数据结构》、《数据结构与算法分析——C语言描述》,这是比较流行的三本C语言实现数据结构的三本书。《数据结构》严版,是类C语言(伪代码)的描述方法,比较容易理解,适合理论学习、应付考试,但是如果用C语言具体实现的话,若C基础不牢固,指针经常容易混淆,尤其是初学者。《大话数据结构》这本跟严蔚敏版数据结构基本相同,是严版的一个子集,内容进行了简化,配上了示例图容易理解,但是讲解不深入,跟严版结合着看不错。《数据结构与算法分析——C语言描述》前半部分容易理解,后半部分比较有深度,而且只是简单的介绍,没有作详细讲解。看这本书的前半部分有种醍醐灌顶的感觉。C代码实现也十分简练。本文讲的主要是参考《数据结构与算法分析——C语言描述》这本书。
单链表(mylist.h)
typedef int ElementType;
#ifndef MYLIST_H
#define MYLIST_H
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
void MakeEmpty(List *L);//创建空链表
int IsEmpty(List L); //判断链表是否为空
int IsLast(Position P); //是否是最后一个节点
Position Find(ElementType X, List L);//查找值为X的节点,并返回该节点的指针
Position FindPrevious(ElementType X, List L);//查找值为X的节点,并返回该节点前驱的指针
void Delete(ElementType X, List L);//删除值为X的节点
void Insert(ElementType X, Position P);//插入节点X
void DestoryList(List *L);//删除链表,头结点一块删除
void ClearList(List L); //清空链表,保留头结点
Position Next(Position P);//节点P的后继
Position First(List L); //返回链表中第一个节点
Position Header(List L); //返回头结点
ElementType Retrieve(Position P);//访问节点P中的数据
#endif
单链表实现(mylist.c)#include "fatal.h"
#include "mylist.h"
#include <stdlib.h>
#include <assert.h>
struct Node
{
ElementType Element;//数据域
PtrToNode Next; //指针域
};
void MakeEmpty(List *L)
{
*L = (Position)malloc(sizeof(struct Node));
if(*L == NULL)
FatalError("Out of space");
(*L)->Next = NULL;
}
int IsEmpty(List L)
{
assert(L != NULL);
return L->Next == NULL;
}
int IsLast(Position P)
{
assert(P != NULL);
return P->Next == NULL;
}
Position Find(ElementType X, List L)
{
Position P = L->Next;
assert(L != NULL);
while(P && P->Element != X)
P = P->Next;
return P;
}
Position FindPrevious(ElementType X, List L)
{
Position P = L;
assert(L != NULL);
while(P->Next != NULL && P->Next->Element != X)
P = P->Next;
return P;
}
void Delete(ElementType X, List L)
{
Position P, TmpCell;
assert(L != NULL);
P = FindPrevious(X, L);
if(!IsLast(P))
{
TmpCell = P->Next;
P->Next = TmpCell->Next;
free(TmpCell);
}
}
//在节点之后插入
void Insert(ElementType X, Position P)
{
Position TmpCell;
assert(P != NULL);
TmpCell = (Position)malloc(sizeof(struct Node));
if(TmpCell == NULL)
FatalError("Out of space");
TmpCell->Element = X;
TmpCell->Next = P->Next;
P->Next = TmpCell;
}
void DestoryList(List *L)
{
Position P = *L;
while(P)
{
*L = P->Next;
free(P);
P = *L;
}
}
void ClearList(List L)
{
Position P, Tmp;
assert(L != NULL);
P = L->Next;
L->Next = NULL;
while(P)
{
Tmp = P->Next;
free(P);
P = Tmp;
}
}
Position Next(Position P)
{
assert(P != NULL);
return P->Next;
}
Position Header(List L)
{
return L;
}
Position First(List L)
{
return L->Next;
}
ElementType Retrieve(Position P)
{
assert(P != NULL);
return P->Element;
}
单链表测试(listmain.c)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "mylist.h"
void PrintList(List L)
{
Position P = L;
assert(L != NULL);
if(IsEmpty(L))
{
printf("List empty\n");
}
else
{
do
{
P = Next(P);
printf("%3d", Retrieve(P));
}while(!IsLast(P));
putchar('\n');
}
}
int main(void)
{
List L;
Position P;
int i;
MakeEmpty(&L);//测试创建空链表
P = L;
for(i = 0; i < 10; i++)
{
Insert(i, P);//测试插入节点
P = Next(P); //测试获取后继
}
PrintList(L); //输出链表中的内容
for(i = 3; i< 7; i++)
Delete(i, L);//测试删除节点
PrintList(L);
for(i = 0; i < 5; i++)
{
if(Find(i, L) != NULL)//测试查找
printf("%d succeed\n", i);
else
printf("%d failed\n", i);
}
printf("Empty: %s\n", IsEmpty(L) ? "yes" : "no");
PrintList(L);
ClearList(L);//测试清空
printf("Empty: %s\n", IsEmpty(L) ? "yes" : "no");
P = L;
for(i = 0; i < 5; i++)
{
Insert(i, P);
P = Next(P);
}
DestoryList(&L);//销毁链表
printf("L == NULL ? %s\n", L == NULL ? "yes" : "no");
printf("Destory list\n");
system("Pause");
return 0;
}
还包括一个定义错误的头文件fatal.h#include<stdio.h>
#include<stdlib.h>
#define FatalError(str) Error(str)
#define Error(str) fprintf(stderr, "%s\n", str), exit(1)