链表操作集完整代码【C语言】详解版

链表操作集完整代码【C语言】详解版

结果

在这里插入图片描述

代码

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
//声明结点结构
typedef struct Link {
	ElementType  elem;//存储自定义类型ElementType类型的元素,根据实际需要通过typedef修改ElementType的具体数据类型
	struct Link *next;//指向直接后继元素的指针
} link;

link * InitLink_H();		//链表创建和初始化的函数
link * Insert(link *p, ElementType elem, int pos);		//链表插入函数,p是链表,elem是插入的结点的数据域,pos是插入的位置
link * Delete(link *p, int pos);		//删除结点的函数,p代表操作链表,pos代表删除节点的位置
int FindElem(link *p, ElementType elem);		//查找结点的函数,elem为目标结点的数据域的值,返回位置 
ElementType FindKth(int pos, link *p);    //按序号查找 ,返回相应位置的数据域元素 
link * Amend(link *p, int pos, ElementType newElem);		//更新结点的函数,newElem为新的数据域的值
void ShowLinkList_H(link *p);		/*输出链表的函数*/
link * ClearLinkList(link *p);      //整表删除
int Length(link *p);		//求链表长


int main() {
	ElementType X,newElem;
	link *p = NULL;
	int pos,i,choice = 99;
	printf("******链表操作主菜单******\n");
	printf("*\t1.创建\t\t*\n*\t2.插入\t\t*\n*\t3.删除\t\t*\n*\t4.查找\t\t*\n*\t5.修改\t\t*\n*\t6.输出\t\t*\n*\t7.清空\t\t*\n*\t8.求表长\t*\n*\t9.按序号查找\t*\n*\t0.退出\t\t*\n************************\n");
	while (choice != 0) {
		printf("\t请输入你的选择(数字):");
		scanf("%d",&choice);
		fflush(stdin);
		switch (choice) {
			case 0:
				printf("\n安全退出程序...");
				exit(0);
			case 1:
				p = InitLink_H();
				break;
			case 2:
				printf("\n请输入要插入的元素X和要插入的位置pos:");
				scanf("%d %d",&X,&pos);
				fflush(stdin);
				p = Insert(p, X, pos);
				break;
			case 3:
				printf("\n请输入要删除的位置pos:");
				scanf("%d", &pos);
				fflush(stdin);
				p = Delete(p, pos);
				break;
			case 4:
				printf("\n请输入要查找的元素X:");
				scanf("%d", &X);
				fflush(stdin);
				i = FindElem(p, X);
				if ( i == -1 ) printf("查找错误: %d 不是此线性表中元素.\n", X);
				else printf("%d 在 %d 处 .\n", X, i);
				break;
			case 5:
				printf("\n请输入要修改的位置和新元素:");
				scanf("%d %d",&pos, &newElem);
				fflush(stdin);
				p = Amend(p, pos, newElem);
				break;
			case 6:
				ShowLinkList_H(p);
				break;
			case 7:
				p = ClearLinkList(p); 
				break;
			case 8:
				printf(" 表长为%d",Length(p));
				break;
			case 9:
				printf("\n请输入要查找的位置:");
				scanf("%d",&pos);
				fflush(stdin);
				printf("\n第%d个位置上的元素为:%d",pos, FindKth(pos,p));
				break;
			default:
				printf("无效选择,请确认菜单有此选项再重新输入!");
				break;
		}
	}
	return 0;
}

//链表初始化和创建(带头结点)
link * InitLink_H() {
	link * p = (link*)malloc(sizeof(link));//创建一个头结点
	link * temp = p;//声明一个指针指向头结点,用于遍历链表
	int i = 0;
	ElementType e;
	printf("\n输入链表元素(以-999结束输入):");
	while (1) {
		//创建结点并初始化
		link *a = (link*)malloc(sizeof(link));
		if (!a) {
			printf("...空间分配失败!");
			exit(0);
		}
		scanf("%d",&e);
		if(e == -999) break;
		a->elem = e;
		a->next = NULL;
		//建立新结点与直接前驱结点的逻辑关系
		temp->next = a;
		temp = temp->next;
	}
	return p;   	//返回建立的节点,只返回头指针 p即可,通过头指针即可找到整个链表
}

//链表插入函数,p为原链表,elem表示新数据元素,pos表示新元素要插入的位置
link * Insert(link * p, ElementType elem, int pos) {
	link * temp = p;//创建临时结点temp
	link * c = NULL;   //用于插入的结点
	int i = 0;
	//首先找到要插入位置的上一个结点
	for (i = 1; i < pos; i++) {
		if (temp == NULL) {
			printf("插入位置无效\n");
			return p;
		}
		temp = temp->next;
	}
	//创建插入结点c
	c = (link*)malloc(sizeof(link));
	c->elem = elem;
	//向链表中插入结点
	c->next = temp->next;
	temp->next = c;
	return  p;
}

//删除结点的函数,p代表操作链表,pos代表删除节点的位置
link * Delete(link * p, int pos) {
	link * temp = p;
	link * del = NULL;
	int i = 0;
	//遍历到被删除结点的上一个结点,用temp指向
	for (i = 1; i < pos; i++) {
		temp = temp->next;
	}
	del = temp->next;//单独设置一个指针指向被删除结点,以防丢失
	temp->next = temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
	free(del);//手动释放该结点,防止内存泄漏
	return p;
}

//查找结点的函数,elem为目标结点的数据域的值
int FindElem(link * p, ElementType elem) {
	//新建一个指针t,初始化为头指针 p
	link * t = p;
	int i = 1;
	//由于头节点的存在,因此while中的判断为t->next
	while (t->next) {
		t = t->next;
		if (t->elem == elem) {
			return i;
		}
		i++;
	}
	//程序执行至此处,表示查找失败
	return -1;
}

/*按序号查找*/
ElementType FindKth (int pos, link *p) {
	link *t = p;
	int i = 0;
	while (t != NULL && i < pos) {
		t = t->next;
		i++;
	}
	if (i == pos) return t->elem;   /*找到第pos个,返回指针*/
	else {
		printf("\t位置参数pos错误..."); 
		return NULL;    /*否则返回空*/
	} 
}

//更新函数,其中,pos 表示更改结点在链表中的位置,newElem 为新的数据域的值
link * Amend(link * p, int pos, ElementType newElem) {
	int i = 0;
	link * temp = p;
	temp = temp->next;//在遍历之前,temp指向首元结点
	//遍历到被删除结点,用temp指向
	for (i = 1; i < pos; i++) {
		temp = temp->next;
	}
	temp->elem = newElem;
	return p;
}

/*输出链表函数,含头结点*/
void ShowLinkList_H(link *p) {
	link* temp = p;//将temp指针重新指向头结点
	//只要temp指针指向的结点的next不是NULL,就执行输出语句。
	printf("\n链表为:"); 
	while (temp->next) {
		temp = temp->next;
		printf("%d ", temp->elem);
	}
	printf("\n");
	return; 
}

//整表删除
link * ClearLinkList(link *p) {
	link *a,*b;
	a=p->next;//a指向第一个结点
	while(a) {
		b=a->next;
		free(a);
		a=b;
	}
	p->next=NULL;//头结点指针域为空
	printf("\n...整个链表已清空...");
	return p;
}

//求表长,link *p指某链表的第一个节点地址放在指针变量p中
int Length(link *p) {
	int len=0;
	link *a=p->next;
	while(a) {
		len++;
		a=a->next;
	}
	return len;
}
/*输出链表函数,不含头结点*/
//void ShowLinkList(link *p) {
//    link* temp = p;//将temp指针重新指向头结点
//    //只要temp指针指向的结点的next不是Null,就执行输出语句。
//    while (temp) {
//        printf("%d ", temp->elem);
//        temp = temp->next;
//    }
//    printf("\n");
//}

//链表初始化和创建(不带头结点)
//link * InitLink() {
//    int i;
//    link * p = NULL;//创建头指针
//    link * temp = (link*)malloc(sizeof(link));//创建首元节点
//    //首元节点先初始化
//    temp->elem = 1;
//    temp->next = NULL;
//    p = temp;//头指针指向首元节点
//    //从第二个节点开始创建
//    for (i = 2; i < 5; i++) {
//        //创建一个新节点并初始化
//        link *a = (link*)malloc(sizeof(link));
//        a->elem = i;
//        a->next = NULL;
//        //将temp节点与新建立的a节点建立逻辑关系
//        temp->next = a;
//        //指针temp每次都指向新链表的最后一个节点,其实就是 a节点,这里写temp=a也对
//        temp = temp->next;
//    }
//    //返回建立的节点,只返回头指针 p即可,通过头指针即可找到整个链表
//    return p;
//}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值