数据结构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成为野指针,结果运行时程序一直挂掉浪费了好长一段时间。切记指针使用时一定要初始化。

运行结果:





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值