数据结构C语言实现——线性链表

declaration.h

#ifndef DECLARATION_H_INCLUDED
#define DECLARATION_H_INCLUDED
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define ElemType int
typedef ElemType* Triplet;
typedef int Status;
typedef struct LNode
{
        ElemType data;
        struct LNode *next;
}LNode, *LinkList;

#endif // DECLARATION_H_INCLUDED

function.h

#ifndef FUNCTION_H_INCLUDED
#define FUNCTION_H_INCLUDED
void CreateList_L(LinkList *L, int n);
//逆序输入n个元素的值,简历带头结点的单链表L
Status ListInsert_L(LinkList *L , int i, ElemType e);
//在带头结点的单链线性表中第i个位置前插入元素e
Status ListDelete_L(LinkList *L, int i, ElemType e);
//在带头结点的单链线性表中,删除第i个元素并由e返回其值
Status GetElem_L(LinkList L, int i, ElemType *e);
//L为带头结点的单链表的头指针
//当第i个元素存在时将其值付给e并返回OK,否则返回ERROR
Status MergeList_L(LinkList *La, LinkList *Lb, LinkList *Lc);
//归并La和Lb表到Lc并按非递减序列排列
void PrintList_L(LinkList L);
//输出单链表中的内容
#endif // FUNCTION_H_INCLUDED

function.c

#include <stdio.h>
#include <stdlib.h>
#include "declaration.h"
void CreateList_L(LinkList *L, int n)
{
        Status i;
        LinkList p;
        *L=(LinkList)malloc (sizeof(LNode));
        (*L)->next=NULL;          //先建立带头结点的单链表;->的优先级比*高不要漏掉这里的括号
        for(i=n; i>0 ;i--)
        {
                p=(LinkList)malloc((sizeof(LNode)));//生成新节点
                 scanf("%d", &p->data);
                 p->next=(*L)->next;   //插入到表头
                (* L)->next=p;  //      数据是倒着插入连表的,即最后输入的数在表头
        }
}//CreateList_L
Status ListInsert_L(LinkList *L , int i, ElemType e)
{
        LinkList p=*L, s;
        ElemType j=0;
        while( p && j < i-1)
        {
                p=p->next;
                j++;
        }
        if(!p || j >i-1)        return ERROR;   //i小于1或大于表长加1
        s=(LinkList)malloc(sizeof(LNode));
        s->data=e;
        s->next=p->next;
        p->next=s;      //先连接后插入
        return OK;
}
Status ListDelete_L(LinkList *L, int i, ElemType *e)
{
        LinkList p=*L, q;
        ElemType j=0;
        while(p->next && j < i-1)
        {
                p=p->next;
                j++;
        }
        if( !(p->next) || j > i-1)        return ERROR;//删除位置不合理
        q=p->next;      p->next=q->next;
        *e=q->data;
        free(q);
        return *e;
}
Status GetElem_L(LinkList L, int i, ElemType *e)
{
        LinkList p;
        ElemType j=1;
        p=L->next;
        while(p && j<i)         //顺序查找直至p指向第i个元素或p为空
        {
                p=p->next;
                j++;
        }
        if( !p || j>i)          return ERROR;      //第i个元素不存在
        *e=p->data;
        return *e;
}//GetElem_L()
Status MergeList_L(LinkList *La, LinkList *Lb, LinkList *Lc)
{
        //La和Lb两个链表中数据非递减排列
        //归并La和Lb表到Lc并按非递减序列排列
        LinkList pa, pb, pc;
        int i=0,j=0;
        pa=(*La)->next;         pb=(*Lb)->next;
        printf("%x      %x",(int )pa,(int )pb);
        (*Lc) =(LinkList)malloc(sizeof(LNode));</span>
        pc=(*Lc);
       while( (int)pa && (int)pb)
        {
                if( (pa->data) <= (pb->data))
                {
                        pc->next =pa;
                        pc=pa;
                        pa=pa->next;
                }
                else
                {
                        pc->next=pb;
                        pc=pb;
                        pb=pb->next;
                }
        }

        while( pa )
        {
                pc->next=pa;//插入剩余段
                pc=pa;
                pa=pa->next;
        }
         while( pb)
         {
                 pc->next=pb;
                 pc=pb=NULL;
         }
        return OK;
}//MergeList_L()
void PrintList_L(LinkList L)
{
        LinkList p;
        for(p=L->next;p;p=p->next)//L为链表的头结点数据域没有赋值
                printf("%d  ",p->data);

        printf("\n");
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include "declaration.h"
#include "function.h"
int main()
{
        ElemType e;
        LinkList *La, *Lb, *Lc;
        La=(LinkList *)malloc(sizeof(LinkList));
        Lb=(LinkList *)malloc(sizeof(LinkList));
        Lc=(LinkList *)malloc(sizeof(LinkList));
        printf("create la ,please enter 5 number:");
        CreateList_L(La, 5);
        printf("la=");
        PrintList_L(*La);
        printf("la表中第3个数是%d\n", GetElem_L(*La, 3, &e));
        printf("删除la表中的第一个数是%d\n", ListDelete_L(La, 1,&e));
        printf("after delete first member ,la=");
         PrintList_L(*La);
        printf("create lb ,please enter 4 number:");
        CreateList_L(Lb, 4);
        printf("lb=");
        PrintList_L(*Lb);
        ListInsert_L(Lb, 2, 3);
        printf("after insert 3, lb =");
        PrintList_L(*Lb);
        printf("MergeList function ,Lc=\n");
        if(MergeList_L(La, Lb, Lc) ==OK)
        {
               printf("merget success\n");
               PrintList_L(*Lc);
        }
        else
                printf("merget failed");

        return 0;
}

分别定义二级指针La,Lb,Lc,将它们作为参数传递到CreateList_L()函数中,这样我们就可以在局部的函数里面为

*La, *Lb, *Lc分配存储空间,这些空间在结束函数调用时是不会消失的。C语言中参数传递都是值传递的方式:若以变量的值作为形参,传入的是一份值的拷贝。函数无返回类型时,对变量值得改变仅在该调用函数内有效;若以指针或数组名坐形参,传递的是变量的地址,同样的在调用函数内对这个地址的改变不会扩散到这个函数外,但对这个地址所代表的内存空间进行赋值,这种改变是永久的,结束调用时也不会被释放。

在实现MergeList_L(LinkList *La, LinkList *Lb, LinkList *Lc)时,一开始忘记为*Lc分配地址空间,使pc成为野指针,结果运行时程序一直挂掉浪费了好长一段时间。切记指针使用时一定要初始化。

运行结果:

数据结构C语言实现——线性链表,布布扣,bubuko.com

时间: 2024-08-29 00:47:26

数据结构C语言实现——线性链表的相关文章

5-6-广义表(扩展线性链表存储表示)-数组和广义表-第5章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第5章  数组和广义表 - 广义表(扩展线性链表存储表示) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.SequenceString.c  

深入浅出数据结构C语言版(5)——链表的操作

上一次我们从什么是表一直讲到了链表该怎么实现的想法上:http://www.cnblogs.com/mm93/p/6574912.html 而这一次我们就要实现所说的承诺,即实现链表应有的操作(至于游标数组--我决定还是给它单独写个博文比较好~). 那么,我们的过程应该是怎么样的呢?首先当然是分析需要什么操作,然后再逐一思考该如何实现,最后再以代码的形式写出来. 不难发现,我们希望链表能支持的(基础,可以由此延伸)操作就是: 1.给出第n个元素 2.在第n个元素的后面插入一个元素(包含在最后一个

数据结构(二):线性表的使用原则以及链表的应用-稀疏矩阵的三元组表示

上一篇博文中主要总结线性表中的链式存储结构实现,比如单向链表.循环链表,还通过对比链表和顺序表的多项式的存储表示,说明链表的优点.可以参看上篇博文http://blog.csdn.net/lg1259156776/article/details/47018813 下面先对没有介绍的链表中的双链表进行介绍,并通过稀疏矩阵的三元组的链式结构来深入理解较为复杂的链表存储结构.最后对三次博文所讲述的内容进行梳理,以帮助在实际应用中选择最合适的存储结构:顺序表和链表,来组织实现自己的算法和功能. 双向链表

数据结构 线性链表

//线性链表头文件 #ifndef _vzhanglinklist #define _vzhanglinklist typedef struct _LinkNode{ struct _LinkNode *pnext; }LinkNode; typedef void LinkList; //创建线性链表 _declspec(dllexport) LinkList* LinkList_Create(); //销毁线性链表 _declspec(dllexport) int LinkList_Destr

看数据结构写代码(52) 广义表的扩展线性链表存储表示

广义表 的另一种 存储结构是 扩展线性链表存储表示,这种 存储结构的 根 节点 必 存在,并且 根节点的 表尾 为空,将 根节点的 表尾 放 在 表头 的 表尾 指针上. 这样 从 表头 一直 就可以 遍历 所有 同级 节点. 具体j结构 如下: 例如 下面的 广义表 ,用 扩展线性链表 表示为: 而 头尾 存储表示,是 把 表头 和 表尾 都放在 根节点 的 指针上.其存储结构如下: 所以 其 实现 代码略有 不同,要 小心 处理 下面 上代码: // GList2.cpp : 定义控制台应用

数据结构第三篇——线性表的链式存储之单链表

线性表的链式存储结构的特点是用一组任意的存储单元来存储线性表的数据元素,这些单元可以分散在内存中的任意位置上,其在物理上可以是连续的,也可以是不连续的.具有链式存储结构的线性表称为线性链表. 为了表示出每个数据元素与其后继之间的关系,除了存储数据元素本身的信息之外,还需存储指示其直接后继的信息.这可以用一个结点(node)来完整的表示. 将节点中存储数据元素本身信息的域称为数据域:存储其直接后继位置的域称为指针域.指针域中存储的信息称作指针或链. 一般情况下,链表中每个结点可以包含若干个数据域和

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

// // 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、链表

链表是一种最简单的数据结构,当我们在使用数组存储数据的时候,频繁的插入和删除会损耗大量的性能,而链表正是一种适合频繁插入删除操作的线性数据结构. 有关链表的详细介绍可以看这里,通俗的来说,链表就是由一些节点构成,每个节点有一个指针,这个指针保存着下一个节点的位置.因此,链表就是由指针将这些物理上没有逻辑关系的节点连接了起来,构成一个有关系的线性表. 我们先来看“单链表”,在C语言当中,具有封装能力的数据类型是结构体.因此,我们用一个结构体来表示一个节点.定义如下: 1 struct Node{

使用C语言实现线性表

线性表是最常用且最简单的一种数据结构.一个线性表是n个数据元素的有限序列,序列中的每个数据元素,可以是一个数字,可以是一个字符,也可以是复杂的结构体或对象.例如:1,2,3,4,5是一个线性表,A,B,C,D...Z是一个线性表,一列列车的车厢1,车厢2...车厢n是一个线性表. 线性表的机内表示法(又称存储结构)有2种,一种是顺序存储结构,另一种是链式存储结构. 顺序存储结构,顾名思义就是按顺序来存储的一种存储结构,比如线性表(1,2,3,4,5),共计5个元素,每个int型的数据元素假设占用