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_INCLUDEDfunction.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_INCLUDEDfunction.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
原文地址:http://blog.csdn.net/codebat/article/details/38542077