线性表的链式表示和实现

来源:互联网 发布:电子传单制作软件 编辑:程序博客网 时间:2024/05/18 12:30
//库函数头文件的包含#include <stdio.h>#include <stdlib.h>#include <malloc.h>//函数状态码定义#define TRUE        1#define FALSE       0#define OK          1#define ERROR       0#define OVERFLOW   -2typedef int  Status;typedef int  ElemType; //假设线性表中的元素均为整型//---------线性表的单链表存储结构--------------typedef struct LNode{    ElemType data;    struct LNode *next;}LNode,*LinkList;//初始化一个空的链表Status InitList_L(LinkList &L){    L = (LinkList)malloc(sizeof(LNode));        //开辟一个头结点    if(!L)                                      //存储空间开辟失败        exit(OVERFLOW);    L->next = NULL;                             //头结点的next赋值为空    return OK;}//向链表末尾插入数据元素Status InsertList_L(LinkList &L, ElemType e){    LNode *p = L, *insertPtr;    while(p->next){        p = p->next;    }    insertPtr = (LNode *)malloc(sizeof(LNode));    if(!insertPtr)        exit(OVERFLOW);    insertPtr->data = e;    insertPtr->next = NULL;    p->next = insertPtr;    return OK;}//返回链表的长度int ListLength_L(LinkList L){    LNode *p = L;    int len = 0;    while(p->next){        p = p->next;        ++len;    }    return len;}//在带头结点的单链线性表L中第i个位置之前插入元素eStatus ListInsert_L(LinkList &L, int i, ElemType e){    LNode *p = L, *insertPtr;    i--;    while(i-- && p->next){        p = p->next;    }    if(!p->next)        return ERROR;    insertPtr = (LNode *)malloc(sizeof(LNode));    insertPtr->data = e;    insertPtr->next = p->next;    p->next = insertPtr;    return OK;}//返回第i个元素的值Status GetElem_L(LinkList L, int i, ElemType &e){    LNode *p = L;    while(i-- && p->next){        p = p->next;    }    if(i > 0)        return ERROR;    e = p->data;    return OK;}//删除链表中第i个元素并返回其值Status ListDelete_L(LinkList &L, int i, ElemType &e){    LNode *p = L, *delPtr;    i--;    while(i-- && p->next){        p = p->next;    }    delPtr = p->next;    e = delPtr->data;    if(delPtr->next)        p->next = delPtr->next;    else        p->next = NULL;    free(delPtr);    return OK;}//若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败pre_e无定义Status PriorElem_L(LinkList L, ElemType cur_e, ElemType &pre_e){    LNode *p = L->next;    if(p->data == cur_e)        return ERROR;    while(p){        if(p->next->data == cur_e)            break;        p = p->next;    }    pre_e = p->data;    return ERROR;}//若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败next_e无定义Status NextElem_L(LinkList L, ElemType cur_e, ElemType &next_e){    LNode *p = L;    while(p->next){        if(p->next->data == cur_e)            break;        p = p->next;    }    p = p->next;    if(p->next)        next_e = p->next->data;    else        return ERROR;    return OK;}//visit()函数Status Print(LNode p){    printf("%d ", p.data);    return OK;}//单链线性链表的遍历Status TraverseList_L(LinkList L, Status (*visit)(LNode)){    LNode *p = L;    while(p->next){        if(!visit(*(p->next)))            return ERROR;        p = p->next;    }    return OK;}//销毁链表Status DestroyList_L(LinkList &L){    LNode *p;    while(L){        p = L->next;        free(L);        L = p;    }    return OK;}//清空链表Status ClearList_L(LinkList &L){    LNode *p, *q;    p = L->next;    while(p){        q = p->next;        free(p);        p = q;    }    L->next = NULL;    return OK;}//判断链表是否为空bool Is_EmptyList(LinkList &L){    if(L->next == NULL)        return true;    return false;}//单链表的就地逆置void ListReverse_L(LinkList &L){     //单链表为空或只有头结点或只有一个元素,不用进行逆置操作    if(L != NULL && L->next != NULL && L->next->next != NULL){        LNode* p = L->next->next;                   //令p指向线性表中第2个元素a2        L->next->next = NULL;                       //令线性表中第1个元素a1的next为空        LNode *tp;                                  //临时变量        while(p){            tp = p->next;                           //保存p->next的地址            p->next = L->next;            L->next = p;                            //将p插入到头结点之后            p = tp;                                 //继续访问下一个元素        }    }}//主函数int main(){    LinkList L;    int a;    InitList_L(L);                          //初始化以带头结点的单链表    printf("请输入5个数字用来创建链表:\n");    for(int i = 0; i < 5; i++){        scanf("%d", &a);        InsertList_L(L, a);    }    printf("下面是遍历操作的的结果:\n");    TraverseList_L(L, Print);    printf("\n下面是删除第5个元素操作后的结果:\n");    ListDelete_L(L, 5, a);    TraverseList_L(L, Print);    printf("\n下面是就地逆置操作的结果:\n");    ListReverse_L(L);    TraverseList_L(L, Print);    printf("\n下面是求链表长度操作的结果:\n");    printf("%d", ListLength_L(L));    printf("\n下面是输出返回2的前驱的结果:\n");    PriorElem_L(L, 2, a);    printf("%d", a);    DestroyList_L(L);    return 0;}

原创粉丝点击