为了找工作,现在有重新拿起了阔别已久的数据结构。《数据结构》严蔚敏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)