线性表的链式表示和实现

//库函数头文件的包含
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define OVERFLOW   -2

typedef 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个位置之前插入元素e
Status 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;
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值