线性链表 (1)

/*
线性链表 
*/
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

typedef struct Node
{
	int data;
	struct Node *next;
}Node,*LinkList;

bool InitList(LinkList *L); //链表的初始化
bool ListInsert(LinkList L,int pos,int e); //在pos位置插入e值
bool ListTraverse(LinkList L); //遍历输出链表的值
void ListEmpty(LinkList L); //判断链表是否为空
bool ClearList(LinkList L); //重置链表为空表
bool GetElem(LinkList L,int pos,int *e); //将链表第pos个位置的值赋给 e
bool comp(int c1,int c2); //数据元素判定函数
int LocateElem( LinkList L,int e,bool (*comper)(int,int) ); //返回L中第1个与e满足关系compare()的数据元素的位序
bool PriorElem(LinkList L,int cur_e,int *pre_e); //若cur_e是L的数据元素,且不是第一个 则用pre_e返回它的前驱
int ListLength(LinkList L); //求L中数据元素的个数
bool NextElem(LinkList L,int cur_e,int *next_e); // 若cur_e是L的数据元素,且不是最后一个 则用next_e返回它的后继
bool ListDelete(LinkList L,int pos,int *e); //删除第pos个元素,并由e返回其值
bool DestoryList(LinkList *L); //销毁线性表L 

int main()
{
	LinkList L; 
	int e, e0;
	int j, k;
	InitList(&L); //链表的初始化 
	for(j = 1; j <= 5; j++)
		ListInsert(L,1,j);  //插入
	printf("在L的表头依次插入1~5后:L = ");
	ListTraverse(L); //遍历
	ListEmpty(L); //判断链表是否为空
	
	ClearList(L); //将L重置为空表

	printf("清空链表后:L = ");
	ListTraverse(L); //遍历
	ListEmpty(L); //清空链表后 判断链表是否为空

	for(j = 1; j <= 10; j++)
		ListInsert(L,j,j);
	printf("在L表的表尾依次插入1-10后 L = ");
	ListTraverse(L);
	GetElem(L,4,&e); //得到链表第4个数据
	printf("第4个元素的值为:%d\n",e);

	for(j = 0; j <= 2; j++)
	{
		k = LocateElem(L,j,comp);
		if(k)
			printf("第%d个元素的值为%d\n",k,j);
		else
			printf("没有值为%d的元素\n");
	}

	for(j = 1; j <= 2; j++) //测试头两个数据
	{
		GetElem(L,j,&e0); //把第j个数据赋给e0
		if( PriorElem(L,e0,&e) ) //求e0的前驱 
			printf("元素%d的前驱为:%d\n",e0,e);
		else
			printf("元素%d无前驱\n",e0);
	}
	
	for(j = ListLength(L) - 1; j <= ListLength(L); j++) //最后两个数据
	{
		GetElem(L,j,&e0);
		if( NextElem(L,e0,&e) ) //求e0的后继
			printf("元素%d的后继为:%d\n",e0,e);
		else
			printf("元素%d无后继\n",e0);
	}

	k = ListLength(L); //k为表长
	
	for(j = k+1; j >= k; j--)
	{
		
		if( ListDelete(L,j,&e) )  //删除第j个元素
		{
		
			printf("删除第%d个元素为:%d\n",j,e);
		}
		else
			printf("删除第%d个元素失败\n",j);
	}
	printf("依次输出L的元素:");
	ListTraverse(L);
	DestoryList(&L);
	printf("销毁L后:L = %d\n",L);
	return 0;
}

bool InitList(LinkList *L)
{
	*L = (LinkList)malloc(sizeof(Node));
	if(*L == NULL)
	{
		printf("内存分配失败 程序终止!\n");
		exit(-1);
	}
	(*L)->next = NULL; //指针域为空
	return true;
}

bool ListInsert(LinkList L,int pos,int e) //在pos位置插入e值
{
	int j = 0;
	LinkList p = L, s;
	while(p != NULL && j < pos - 1)
	{
		p = p->next;
		j++;
	}
	if(p == NULL || j > pos - 1)
		return false;
	s = (LinkList)malloc(sizeof(Node)); //生成新节点
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}

bool ListTraverse(LinkList L) //遍历输出链表的值
{
	LinkList p = L->next;
	while(p != NULL)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
	return true;
}

void ListEmpty(LinkList L) //判断链表是否为空
{
	if(L->next == NULL)
		printf("链表为空\n");
	else
		printf("链表不为空\n");
}

bool ClearList(LinkList L) //重置链表为空表
{
	LinkList p, q;
	p = L->next; //p指向第一个结点
	while(p != NULL)
	{
		q = p->next;
		free(p);
		p = q;
	}
	L->next = NULL;
	return true;
}

bool GetElem(LinkList L,int pos,int *e) //将链表第pos个位置的值赋给 e
{
	int j = 1; //j 为计数器
	LinkList p = L->next; //p指向第一个结点
	while(p != NULL && j < pos) //顺指针向后查找,直到p指向第pos个元素 或 p 为空
	{
		p = p->next;
		j++;
	}
	if(p == NULL || j > pos)
		return false;
	*e = p->data;
	return true;
}

bool comp(int c1,int c2) //数据元素判定函数
{
	if(c1 == c2)
		return true;
	else
		return false;
}

int LocateElem( LinkList L,int e,bool (*compare)(int,int) )
{
	int i= 0;
	LinkList p = L->next;
	while(p != NULL)
	{
		i++;
		if( compare(p->data,e) )
			return i;
		p = p->next;
	}
	return 0;
}

bool PriorElem(LinkList L,int cur_e,int *pre_e) //若cur_e是L的数据元素,且不是第一个 则用pre_e返回它的前驱
{
	LinkList q, p = L->next; //p指向第一个结点
	while(p->next != NULL) //p所指结点有后继
	{
		q = p->next; //q 为 p 的后继
		if(q->data == cur_e)
		{
			*pre_e = p->data;
			return true;
		}
		p = q; //p向后移
	}
	return false;
}

int ListLength(LinkList L) //求L中数据元素的个数
{
	int i = 0;
	LinkList p = L->next; //p 指向第一个结点
	while(p != NULL) //没有到表尾
	{
		i++;
		p = p->next;
	}
	return i;
}

bool NextElem(LinkList L,int cur_e,int *next_e)
{
	LinkList p = L->next; //p指向第一个结点
	while(p->next != NULL) //p所指的结点有后继
	{
		if(p->data == cur_e)
		{
			*next_e = p->next->data;
			return true;
		}
		p = p->next;
	}
	return false;
}

bool ListDelete(LinkList L,int pos,int *e) //删除第pos个元素,并由e返回其值
{
	int j = 0;
	LinkList p = L, q;
	while(p->next != NULL && j < pos - 1) //寻找第i个结点,并令p指向其前驱
	{
		p = p->next;
		j++;
	}
	if(p->next == NULL || j > pos - 1)
		return false;
	q = p->next; //以下几行删除并释放结点
	p->next = q->next;
	*e = q->data;
	free(q);
	return true;
}

bool DestoryList(LinkList *L) //销毁线性表L 
{
	LinkList q;
	while(*L)
	{
		q = (*L)->next;
		free(*L);
		*L = q;
	}
	return true;
}

程序执行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值