数据结构线性链表(单链表)

Posted tp0829

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构线性链表(单链表)相关的知识,希望对你有一定的参考价值。

//
//  main.cpp
//  LinkList
//
//  Created by T.P on 2019/1/31.
//  Copyright ? 2019 T.P. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>//malloc free

#define TRUE 1
#define FALSE 0
#define OK 0
#define ERROR -1
#define INFEASIBLE -1   //不可实行的
#define OVERFLOW -2     //溢出

typedef struct LNode{//LNode(结构名)
    int data;
    struct LNode *next=NULL;
}LNode,*LinkList;//LNode("struct LNode"的别名)

//线性链表L(未建立) | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//初始化 | 建立L的头结点[给L的头结点分配空间]
int InitList_L(LinkList &L){//此处修改了指针L,故需要用"引用"
    L=(LinkList)malloc(sizeof(LNode));//建立头结点,别忘记给头结点元素赋初值
    L->data=0;
    L->next=NULL;
    if(!L)
        exit(OVERFLOW);
    return 0;
}

//线性链表L[已建立] | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//释放链表 | 释放L的头结点+后续节点
int FreeList_L(LinkList &L){//此处修改了指针L,故需要用"引用"
    LinkList temporary=L;
    while(temporary->next!=NULL){
        temporary=L->next;
        L->next=temporary->next;
        free(temporary);
    }
    free(L);
    return 0;
}

//打印线性链表元素
int Print_L(LinkList &L){//此处没有修改指针L,故可以不用"引用"
    LinkList p=L;//p指向头结点(第零个结点)
    while (p->next) {//打印y链表元素(不包括头结点)
        printf("%d ",p->next->data);
        p=p->next;
    }
    printf("
");
    return 0;
}

//ALGORITHM_2_8
//在线性链表L中 | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//用e返回L中第i元素的值 | i从1计数
int GetElem_L(LinkList &L,int i,int &e){//此处没有修改指针L,故可以不用"引用"
    LinkList p=L;//p指向头结点
    int j=0;//第0结点
    while (p&&j<i) {//找到第i结点(j=0头结点/j=1第1结点)
        p=p->next;
        ++j;
    }
    if(!p||i<=0)//p为空/i输入错误 | 教材中(j>i)??
        return ERROR;
    e=p->data;
    return OK;
}

//ALGORITHM_2_9
//在线性链表L中 | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//第i位置之前插入新的元素e | i从1计数
int InsertList_L(LinkList &L,int i,int e){//此处没有修改指针L,故可以不用"引用"
    LinkList p=L;//p指向头结点(第零个结点)
    int j=0;//第0结点
    while (p&&j<i-1) {//找到第i-1结点(j=0头结点/j=1第1结点)
        p=p->next;
        ++j;
    }
    if(!p||i<=0)//p为空/i输入错误 | ??教材中if(!p||j>i-1)
        return ERROR;
    LinkList s=(LinkList)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s;
    return 0;
}

//ALGORITHM_2_10
//在线性链表L中 | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//删除第i元素并用e返回其值 | i从1计数
int DeleteList_L(LinkList &L,int i,int &e){//此处没有修改指针L,故可以不用"引用"
    LinkList p=L;//p指向头结点(第零个结点)
    int j=0;//第0结点
    while (p&&j<i-1) {//找到第i-1结点(j=0头结点/j=1第1结点)
        p=p->next;
        ++j;
    }
    if(!p||i<=0)//p为空/i输入错误 | ??教材中if(!p||j>i-1)
        return ERROR;
    LinkList s=p->next;
    p->next=s->next;
    e=s->data;
    free(s);
    return 0;
}

//ALGORITHM_2_11
//线性链表L(未建立) | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//逆位序输入n个元素的值
int CreateList_L(LinkList &L,int n){//此处修改了指针L,故需要用"引用"
    L=(LinkList)malloc(sizeof(LNode));//建立头结点,别忘记给头结点元素赋初值
    L->data=0;
    L->next=NULL;
    for(int i=n;i>0;--i){
        LinkList p=(LinkList)malloc(sizeof(LNode));
        scanf("%d",&p->data);
        p->next=L->next;
        L->next=p;
    }
    return 0;
}

//ALGORITHM_2_12
//线性链表La,Lb元素按值非递减排列(递增)
//归并La,Lb得到新的单链表Lc,Lc的s值也按值非递减排列(递增)
int MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){//此处修改了指针L,故需要用"引用"
    Lc=(LinkList)malloc(sizeof(LNode));//建立头结点,别忘记给头结点元素赋初值
    Lc->data=0;
    Lc->next=NULL;
    LinkList La_p=La->next;//需要指向第一个节点
    LinkList Lb_p=Lb->next;
    LinkList Lc_p=Lc;
    while(La_p!=NULL&&Lb_p!=NULL){//注意Lc的最后一个节点的next要置空
        if(La_p->data<Lb_p->data){
            Lc_p->next=La_p;
            Lc_p=Lc_p->next;
            La_p=La_p->next;
        }
        else{
            Lc_p->next=Lb_p;
            Lc_p=Lc_p->next;
            Lb_p=Lb_p->next;
        }
    }
    if(La_p!=NULL)          //条件运算符 Lc_p->next=La_p?La_p:Lb_p
        Lc_p->next=La_p;
    else
        Lc_p->next=Lb_p;
    return 0;
}


int main(int argc, const char * argv[]) {

    printf("OK
");
    //LinkList a;//错误,该定义只是定义了一个指针并没有分配空间
    //LNode a;//分配了空间
    //注:因为是指针操作故函数传参不再需要"引用操作"
    //也可如下操作:
    //LinkList a;
    //InitList_L(a);

    LinkList a;
    LinkList b;
    LinkList c;
    CreateList_L(a,4);
    Print_L(a);
    printf("OK
");
    CreateList_L(b, 5);//需要输入
    Print_L(b);
    printf("OK
");
    MergeList_L(a,b,c);
    Print_L(c);
    
    return 0;
}

以上是关于数据结构线性链表(单链表)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构--单链表简单代码实现(总结)

数据结构(线性表之单链表)

线性数据结构案例2 —— 单链表反转

数据结构:线性表顺序表以及单链表详解

线性表——链表实现(单链表)

数据结构线性表之实现单链表