数据结构c语言实现之单链表

//c语言实现单链表,参考严蔚敏书本代码
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1

typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int ElemType;
//线性表的单链表存储结构
struct LNode
{
	ElemType data;
	LNode *next;
};
typedef LNode *LinkList; // 另一种定义LinkList的方法


void CreateList(LinkList &L,int n) // 算法2.11
{ // 逆位序(插在表头)输入n个元素的值,建立带表头结构的单链线性表L
	int i;
	LinkList p;
	L=(LinkList)malloc(sizeof(LNode));
	L->next=NULL; // 先建立一个带头结点的单链表
	printf("请输入%d个数据\n",n);
	for(i=n;i>0;--i)
	{
		p=(LinkList)malloc(sizeof(LNode)); // 生成新结点
		scanf("%d",&p->data); // 输入元素值
		p->next=L->next; // 插入到表头
		L->next=p;
	}
}

void CreateList2(LinkList &L,int n)
{ // 正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表L
	int i;
	LinkList p,q;
	L=(LinkList)malloc(sizeof(LNode)); // 生成头结点
	L->next=NULL;
	q=L;
	printf("请输入%d个数据\n",n);
	for(i=1;i<=n;i++)
	{
		p=(LinkList)malloc(sizeof(LNode));
		scanf("%d",&p->data);
		q->next=p;
		q=q->next;
	}
	p->next=NULL;
}
// bo2-2.cpp 带有头结点的单链表(存储结构由c2-2.h定义)的基本操作(12个),包括算法2.8,2.9,2.10
void InitList(LinkList &L)
{ // 操作结果:构造一个空的线性表L
	L=(LinkList)malloc(sizeof(LNode)); // 产生头结点,并使L指向此头结点
	if(!L) // 存储分配失败
		exit(OVERFLOW);
	L->next=NULL; // 指针域为空
}

void DestroyList(LinkList &L)
{ // 初始条件:线性表L已存在。操作结果:销毁线性表L
	LinkList q;
	while(L)
	{
		q=L->next;
		free(L);
		L=q;
	}
}

void ClearList(LinkList L) // 不改变L
{ // 初始条件:线性表L已存在。操作结果:将L重置为空表
	LinkList p,q;
	p=L->next; // p指向第一个结点
	while(p) // 没到表尾
	{
		q=p->next;
		free(p);
		p=q;
	}
	L->next=NULL; // 头结点指针域为空
}

Status ListEmpty(LinkList L)
{ // 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE
	if(L->next) // 非空
		return FALSE;
	else
		return TRUE;
}

int ListLength(LinkList L)
{ // 初始条件:线性表L已存在。操作结果:返回L中数据元素个数
	int i=0;
	LinkList p=L->next; // p指向第一个结点
	while(p) // 没到表尾
	{
		i++;
		p=p->next;
	}
	return i;
}

Status GetElem(LinkList L,int i,ElemType &e) // 算法2.8
{ // L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
	int j=1; // j为计数器
	LinkList p=L->next; // p指向第一个结点
	while(p&&j<i) // 顺指针向后查找,直到p指向第i个元素或p为空
	{
		p=p->next;
		j++;
	}
	if(!p||j>i) // 第i个元素不存在
		return ERROR;
	e=p->data; // 取第i个元素
	return OK;
}

int LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{ // 初始条件: 线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
	// 操作结果: 返回L中第1个与e满足关系compare()的数据元素的位序。
	//           若这样的数据元素不存在,则返回值为0
	int i=0;
	LinkList p=L->next;
	while(p)
	{
		i++;
		if(compare(p->data,e)) // 找到这样的数据元素
			return i;
		p=p->next;
	}
	return 0;
}

Status PriorElem(LinkList L,ElemType cur_e,ElemType &pre_e)
{ // 初始条件: 线性表L已存在
	// 操作结果: 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,
	//           返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE
	LinkList q,p=L->next; // p指向第一个结点
	while(p->next) // p所指结点有后继
	{
		q=p->next; // q为p的后继
		if(q->data==cur_e)
		{
			pre_e=p->data;
			return OK;
		}
		p=q; // p向后移
	}
	return INFEASIBLE;
}

Status NextElem(LinkList L,ElemType cur_e,ElemType &next_e)
{ // 初始条件:线性表L已存在
	// 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,
	//           返回OK;否则操作失败,next_e无定义,返回INFEASIBLE
	LinkList p=L->next; // p指向第一个结点
	while(p->next) // p所指结点有后继
	{
		if(p->data==cur_e)
		{
			next_e=p->next->data;
			return OK;
		}
		p=p->next;
	}
	return INFEASIBLE;
}

Status ListInsert(LinkList L,int i,ElemType e) // 算法2.9。不改变L
{ // 在带头结点的单链线性表L中第i个位置之前插入元素e
	int j=0;
	LinkList p=L,s;
	while(p&&j<i-1) // 寻找第i-1个结点
	{
		p=p->next;
		j++;
	}
	if(!p||j>i-1) // i小于1或者大于表长
		return ERROR;
	s=(LinkList)malloc(sizeof(LNode)); // 生成新结点
	s->data=e; // 插入L中
	s->next=p->next;
	p->next=s;
	return OK;
}

Status ListDelete(LinkList L,int i,ElemType &e) // 算法2.10。不改变L
{ // 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
	int j=0;
	LinkList p=L,q;
	while(p->next&&j<i-1) // 寻找第i个结点,并令p指向其前驱
	{
		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 OK;
}

void ListTraverse(LinkList L,void(*vi)(ElemType))
// vi的形参类型为ElemType,与bo2-1.cpp中相应函数的形参类型ElemType&不同
{ // 初始条件:线性表L已存在。操作结果:依次对L的每个数据元素调用函数vi()
	LinkList p=L->next;
	while(p)
	{
		vi(p->data);
		p=p->next;
	}
	printf("\n");
}
// func2-3.cpp 几个常用的函数
Status equal(ElemType c1,ElemType c2)
{ // 判断是否相等的函数
	if(c1==c2)
		return TRUE;
	else
		return FALSE;
}

int comp(ElemType a,ElemType b)
{ // 根据a<、=或>b,分别返回-1、0或1
	if(a==b)
		return 0;
	else
		return (a-b)/abs(a-b);
}
void print(ElemType c)
{
	printf("%d ",c);
}
void print2(ElemType c)
{
	printf("%c ",c);
}
void print1(ElemType &c)
{
	printf("%d ",c);
}
void MergeList(LinkList La,LinkList &Lb,LinkList &Lc) // 算法2.12
{ // 已知单链线性表La和Lb的元素按值非递减排列。
	// 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
	LinkList pa=La->next,pb=Lb->next,pc;
	Lc=pc=La; // 用La的头结点作为Lc的头结点
	while(pa&&pb)
		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); // 释放Lb的头结点
		Lb=NULL;
}

void main()
{
	int n=5;
	LinkList La,Lb,Lc;
	printf("按递增顺序, ");
	CreateList2(La,n); // 正位序输入n个元素的值
	printf("La="); // 输出链表La的内容
	ListTraverse(La,print);
	printf("按递减顺序, ");
	CreateList(Lb,n); // 逆位序输入n个元素的值
	printf("Lb="); // 输出链表Lb的内容
	ListTraverse(Lb,print);
	MergeList(La,Lb,Lc); // 按非递减顺序归并La和Lb,得到新表Lc
	printf("Lc="); // 输出链表Lc的内容
	ListTraverse(Lc,print);
	printf("等待退出\n");
	//fflush(stdout);
	//getchar();//有时竟然失效 不能暂停,
	int m;
	scanf("%d",&m);
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值