本文是对严蔚敏老师《数据结构》线性表的链式表示和实现这节的算法用C语言的实现,已成功在Linux上运行。
#include <stdlib.h>
#include <malloc.h>
//函数结果代码
#define TRUE 1
#define FALSE 0
#define OK 0
#define ERROR 1
#define OVERFLOW -1
typedef int Status; //函数的类型,其结果是函数结果状态代码
//线性表的单链表存储结构
typedef struct LNode{
int data; //数据域
struct LNode * next; //指针域
}LNode, * LinkList;
//函数声明
void CreateList_L(LinkList *, int);
Status TraverseList_L(LinkList);
Status GetElem(LinkList,int,int *);
Status ListInsert_L(LinkList *, int, int);
Status ListDelete_L(LinkList *, int, int *);
void MergerList_L(LinkList, LinkList, LinkList *);
Status main(void)
{
//int e;
LinkList La, Lb, Lc; //头指针
CreateList_L(&La, 4);
TraverseList_L(La);
CreateList_L(&Lb, 7);
TraverseList_L(Lb);
MergerList_L(La,Lb,&Lc);
TraverseList_L(Lc);
//ListInsert_L(&L,3,100);
//TraverseList_L(L);
//ListDelete_L(&L,3,&e);
//printf("%d\n",e);
//TraverseList_L(L);
//GetElem(L,3,&e);
//printf("%d\n",e);
return OK;
}
//创建链表,逆位序输入n个元素的值,建立带表头结点的单链表线性表L
void CreateList_L(LinkList * L, int n)
{
int i;
LinkList p;
*L = (LinkList)malloc(sizeof(LNode)); //头结点
(*L)->next = NULL; //先创建一个带有头结点的空链表
for (i=n; i>0; --i) {
p = (LinkList)malloc(sizeof(LNode)); //生成新结点
printf("请输入第%d个结点的值:",i);
scanf("%d",&p->data);
p->next = (*L)->next; //插入到表头
(*L)->next = p;
}
}
//遍历输出
Status TraverseList_L(LinkList L)
{
LinkList p = L->next;
if (NULL == p) { //判断线性表是否为空
printf("线性表为空!\n");
return ERROR;
}
while (p) {
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
return OK;
}
//用e返回L中第i个数据元素的值. 若第i个元素不存在则返回ERROR
Status GetElem(LinkList L,int i,int * e)
{
int j = 1; //j为计数器
LinkList p = L->next; //p指向第一个结点
while (p && (j<i)) { //顺指针向后查找,直到p指向第i个元素或p为空
p = p->next;
++j;
}
if (!p || (j>i)) //!p保证i在链表的长度之内,j>i保证i不比1小
return ERROR; //第i个元素不存在
*e = p->data; //取出第i个元素的值
return OK;
}
//在带头结点的单链表L中的第i个位置之前插入新的数据元素e
Status ListInsert_L(LinkList * L, int i, int e)
{
int j = 1; //j为计数器
LinkList p,s;
p = *L; //p指向头结点
while (p && (j<i)) { //顺指针向后查找,直到p指向第i个元素或p为空
p = p->next;
++j;
}
if (!p || (j>i)) //!p保证i在链表的长度之内,j>i保证i不比1小
return ERROR; //第i个元素不存在
s = (LinkList)malloc(sizeof(LNode)); //生成新结点
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
//在带头结点的单链表L中,删除第i个结点,并由e返回其值
Status ListDelete_L(LinkList * L, int i, int * e)
{
int j = 1; //j为计数器
LinkList p,q;
p = *L; //p指向头结点
while (p && (j<i)) { //顺指针向后查找,直到p指向第i个元素或p为空
p = p->next;
++j;
}
if (!p || (j>i)) //!p保证i在链表的长度之内,j>i保证i不比1小
return ERROR; //第i个元素不存在
q = p->next;
p->next = q->next; //删除结点
*e = q->data;
free(q); //释放结点
return OK;
}
//已知单链表表La和Lb中的数据元素按值非递减排序,归并La和Lc得到新的单链表Lc,Lc的数据元素也按值非递减排序
void MergerList_L(LinkList La, LinkList Lb, LinkList * Lc)
{
LinkList pa, pb, pc;
pa = La->next;
pb = Lb->next;
*Lc = pc = La; //用La的头结点作为Lc的头结点
while (pa && pb ) { //La和Lb均非空
if ( pa->data <= pb->data) {
pc->next = pa;
pc = pa;
pa = pa->next;
}else {
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
pc->next = pa?pa:pb;
free(Lb);
return;
}