数据结构——单链表

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

你可能感兴趣的:(数据结构,C语言,单链表)