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

来源:互联网 发布:淘宝经销和代销的区别 编辑:程序博客网 时间:2024/04/29 11:46

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 inttypedef 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_INCLUDEDvoid CreateList_L(LinkList *L, int n);//逆序输入n个元素的值,简历带头结点的单链表LStatus ListInsert_L(LinkList *L , int i, ElemType e);//在带头结点的单链线性表中第i个位置前插入元素eStatus ListDelete_L(LinkList *L, int i, ElemType e);//在带头结点的单链线性表中,删除第i个元素并由e返回其值Status GetElem_L(LinkList L, int i, ElemType *e);//L为带头结点的单链表的头指针//当第i个元素存在时将其值付给e并返回OK,否则返回ERRORStatus 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_LStatus 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成为野指针,结果运行时程序一直挂掉浪费了好长一段时间。切记指针使用时一定要初始化。

运行结果:





1 0
原创粉丝点击