数据结构与算法分析-用C语言实现单链表

掌握单链表很容易,把下面的代码弄懂,敲几遍,全部记住,而且记清每一个细节。

首先,在List.h中声明单链表的ADT.我们把我们所需要的自定义类型啊,函数啊,都声明出来,但这里我们只是声明他们,而具体实现则是在List.c中进行。

/**
* @file    List.h
* @brief   单链表的声明
* @details
* @author   mrbourne@163.com
* @date     2014-5-19
*/
#ifndef _List_H

//先声明实现单链表时所需的类型和结构,包括一个节点结构体,元素类型,指向元素的指针类型(同样可以用来表示单链表本身和元素位置)
struct Node;
typedef int ElementType;    //此处根据链表中元素类型的不同 可以修改
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;

//接下来声明一些常用的函数,一定要记住这些函数,因为这些函数都是最常用最基础的
List MakeEmpty(List L); //置空链表
int IsEmpty(List L);    //判空链表
int IsLast(Position P,List L);  //判断是否为表尾
Position Find(ElementType X,List L);    //找出元素所在位置
void Delete(ElementType X,List L);      //删除元素
Position FindPrevious(ElementType X,List L);    //找到某元素的前驱
void Insert(ElementType X,List L,Position P);   //插入一个元素
void DeleteList(List L);    //删除链表
Position Header(List L);    //返回头结点
Position First(List L);     //返回第一个元素
Position Advance(Position P);   //返回后一个位置
ElementType Retrieve(Position P);   //获取位置P处的元素值

#endif // _List_H

声明完了以后,我们就要逐步实现这些单链表的ADT,实现的代码放在List.c中

具体实现代码如下:

/**
* @file    List.h
* @brief   链表的实现部分
* @details
* @author   mrbourne@163.com
* @date     2014-5-19
*/
#include <stdio.h>
#include <stdlib.h>
#include <List.h>	//别忘了先把声明部分的头文件List.h包含进来

//实现节点结构体
struct Node
{
    ElementType Element;	//元素
    Position    Next;		//指向下个元素的指针
};

//空链表返回true
int IsEmpty(List L)
{
    return L->Next == NULL;
}

//当前位置是否为链表末尾
int IsLast(Position P, List L)
{
    return P->Next == NULL;
}

//找到一个元素所在的位置
Position Find(ElementType X, List L)
{
    Position P;
    P = L->Next;    //P初始化为a1
    while(P != NULL && P->Element != X)		//只要没到表尾,且当前节点中的元素不等于所给参数,就一直向后遍历
        P = P->Next;
    return P;
}
//找到某个元素的前驱
Position FindPrevious(ElementType X, List L)
{
    Position P;
    while(P->Next != NULL && P->Next->Element != X)	//下一个元素没到表尾,且下一个元素不匹配,则继续遍历
        P = P->Next;
    return P;
}

//删除某个元素x
void Delete(ElementType X, List L)
{
    Position P,TmpCell; //前驱和当前节点
    P = FindPrevious(X,L);
    if(!IsLast(P,L))    //成功找到了该元素的前驱,若IsLast成立,则表示没有找到前驱
    {
        TmpCell = P->Next;	
        P->Next = TmpCell->Next;
        free(TmpCell);
    }
}

//打印错误信息
void FatalError(char *str)
{
    printf("%s\n", str);
}

//在某个元素前插入一个元素
void Insert(ElementType X, List L, Position P)
{
    Position NewCell;
    NewCell = malloc(sizeof(struct Node));  //申请空间
    if(NewCell == NULL)
        FatalError("Out of space!!!");

    NewCell->Element = X;
    NewCell->Next = P->Next;
    P->Next = NewCell;
}

//删除一个链表
void DeleteList(List L)
{
    Position P,Tmp;
    P = L->Next;
    L->Next = NULL; //释放头结点
    while(P != NULL)    //需要用Tmp保存当前节点 因为在free(P)后 不能再对P引用进行P = P->Next
    {
        Tmp = P->Next;
        free(P);
        P = Tmp;
    }

}

至此,我们已经基本实现一个单链表和其基础的操作。这里有几个例程并没有实现,不要着急,这里的单链表还不能供我们使用,有几个历程和后面我们实现栈和队列时大同小异,等学完栈和队列,我们再回来把剩下的几个例程补上,然后也像测试栈和队列一样,在主程序中来测试一下单链表。



posted @ 2014-05-19 23:12  庄浩  阅读(161)  评论(0编辑  收藏  举报