C语言:功能齐全的链表代码

此链表可以实现创建,输入,序号查找,数值查找,插入,删除,输出等功能
代码:

#include<stdio.h>
#include<stdlib.h>
//链表的结构体 
typedef struct linklist{
	int data;//存放数字 
	struct linklist *next;//指向下一个节点的指针 
	
}*LinkList;

//菜单 (用来画出菜单的函数) 
void Menu(void);
//长度(用来测量链表长度的函数) 
int Length(LinkList head);
//创建一个新链表(其实就是将前面的链表清除后建个新的表头) 
void CreateList(LinkList *head);
//输入 
void IntoList(LinkList head);
//按序号查找(输入序号,查找该序号上的数字) 
void Findkth(LinkList head);
//按值查找(输入值,查找其第一次出现的位置且求出其总共出现的次数) 
void Find(LinkList head);
//插入(输入序号在该位置插入数字) 
void Insert(LinkList head);
//删除(输入序号,删除该位置上的数字) 
void Delete(LinkList head);
//输出(将链表中的值全部输出) 
void OutList(LinkList head);
//清除(将链表全部释放) 
void ClearList(LinkList head);

int main(void)
{	
  LinkList head=NULL;//用来当表头 
  int trigger;//用户选择服务 
  
  while(1)
  {
  	
  	Menu();
    scanf("%d",&trigger);
    system("cls");
    switch(trigger)
    {
    	case 1: CreateList(&head);   	
				    break;
		case 2: IntoList(head);	
    	            break;
    	case 3: Findkth(head);
    	             break;
    	case 4: Find(head);
    	             break;
        case 5: Insert(head);
                     break;
        case 6: Delete(head);
                      break;
        case 7: OutList(head);
                     break;
        case 8: ClearList(head);
                     break;
    	case 0: ClearList(head);
		           return 0;            
  	    
     }
	}
	
	return 0;
}
void Menu(void)
{      
	puts("---------------------");
	puts("1.创建一个新链表");
	puts("2.输入数据");
	puts("3.按序号查找");
	puts("4.按值查找");
	puts("5.插入");
	puts("6.删除");
	puts("7.输出数据");
	puts("8.清空链表"); 
	puts("0.退出"); 
	puts("---------------------");
   
}
//长度 
int Length(LinkList head)
{
	int i; 
	LinkList pre;
	pre=head;
	for(i=0;pre->next!=NULL;i++)//当pre->next!=NULL时说明该链表到头了 
	{
		pre=pre->next;//若无到头,则继续往下一个节点移动 
	}
	return i;//将长度返回 
}
//创建新链表 
void CreateList(LinkList *head)//这里面传入了前面旧链表的表头的地址 
{
	if(*head!=NULL) ClearList(*head);//如果旧链表不是空链表就先把它存的东西释放掉 
	
	*head=(LinkList)malloc(sizeof(struct linklist));//为旧表头申请个新的空间,他就成新表头了 
	if(*head==NULL)//判断表头新建成没 
	{
		printf("新建链表失败!!!\n"); 
	}else{
		(*head)->next=NULL;
		printf("新建链表成功!!!\n"); 
	}	
}
/*输入*/ 
void IntoList(LinkList head)
{
   LinkList pri,pre;
   //先让pri指向表尾    
   	for(pri=head;pri->next!=NULL;pri=pri->next)
   	 continue;
   	 
     while(1)
   {   	
   	pre=(LinkList)malloc(sizeof(struct linklist));//为现在要输入的数字申请空间 
   	if(pre==NULL)
   	{
   		printf("申请空间失败!!!\n"); 
   		break;
	   }	   
	 //用户输入数字 
	int number;
	printf("请输入要存储的数字(若已输入完毕则输入-1以结束输入):\n");
	scanf("%d",&number);
	//判断数字是否为负一,不是则存,是则退出该函数 
	if(number!=-1)
	{
	  pre->data=number;
	  pre->next=NULL;
	  pri->next=pre;
	  pri=pre;
	  puts("输入完成!!!");
	}else return;		  
   }    	
}
//按序号找值 
void Findkth(LinkList head)//这里将表头传进来 
{    
    int number,i;//一个位置,一个为该位置上的值 
    LinkList pre;//用来查找的指针 
    pre=head;//指向表头 
	puts("请输入你要查看序号:");
	scanf("%d",&number);
	//开始查找该位置上的值 
	if(number<=0||number>Length(head))  //位置过小或超过表的长度 
	{
		puts("数字违规!!!!"); 
	}
   for(i=0;pre!=NULL&&i<=number;i++)//遍历该链表 
   {
   	//当pre指向该位置时 
   	if(i==number) 
   	{
   		printf("第%d个位置上的数字是%d\n",number,pre->data);//输出该位置上的值 
   		return;
	   }
   	pre=pre->next;//没找到则指向下一个节点 
   }   		
}
//按值查找 
void Find(LinkList head)//这里只要传入表头就行 
{
	int number,time=0,i;//目标数字,出现次数,第一次出现的位置 
	printf("请输入你要查找的数字\n");
	scanf("%d",&number);
	LinkList pre;//用来遍历的指针 
	pre=head;
	for(int j=0;pre!=NULL;j++)
	{
		if(pre->data==number)
		{
			if(time==0)
			 i=j;	//第一次出现时的位置		 
			time++;//每出现一次time都加一			
		}
		pre=pre->next;
	}
//	找完了 
	if(time==0) //如果该链表里没有出现过目标数字 
	{
		printf("%d不存在此链表中",number);
		return;
	}else{
		printf("%d在此链表中总共出现%d次,第一次出现在%d号位上\n",number,time,i);
	}	
 } 
 //插入 
void Insert(LinkList head)//这里传入的是表头的地址 
 {
 	int place;//目标位置 
 	printf("请输入你想插入的位置:\n"); 
 	scanf("%d",&place);
 	//看看位置是否和合规范 
 	if(place<=0||place>Length(head))
 {
 	printf("位置违法!!%d\n",Length(head));
 	return;
 }
 	
 	LinkList pri,pre;
 	pre=(LinkList)malloc(sizeof(struct linklist));//先为要插入的数字申请空间 
 	printf("请输入要插入的数据\n");
 	scanf("%d",&pre->data);
 	//找位置 
 	pri=head;
    	for(int i=0;i<=place;i++)
	 	{
	 		if(i==place-1)//先找到目标位置的前一个节点 
	 		{
	 			pre->next=pri->next;
	 			pri->next=pre;
	 			puts("插入成功!!");
	 			break;
			 }
			 pri=pri->next;
		 }	 	 
 }
 //删除 
void Delete(LinkList head)
{
	int place;
	LinkList pri,pre;
	puts("请输入你想删除的位置:");
	scanf("%d",&place);
	if(place<0||place>Length (head))
	{
		printf("违规数字!!!\n");
		return; 
	}
     	pre=head;		
		for(int i=0;i<=place;i++)
		{
			if(i==place-1)
			{
				pri=pre;
			}
			if(i==place)
			{
				pri->next=pre->next;
				free(pre);
				puts("删除完毕!!"); 
				return;
			}
			pre=pre->next;
		}
}
//输出 
void OutList(LinkList head)
{
	LinkList pre;	
	pre=head->next;
	if(head->next==NULL) puts("该表为空表!!!!"); 
	while(pre!=NULL)
	{
		printf("%d\n",pre->data);
		pre=pre->next;
	}
}
//清除 
void ClearList(LinkList head)
{
	LinkList pri,pre;	
	for(pre=head->next;pre!=NULL;pre=pri)
	{
		    pri=pre->next;
			free(pre);
	}
	head->next=NULL;
	puts("链表清空完毕!!");
}

代码比较长,今天肝了一下午加一晚上,注释就后面在写了,让我先休息一下下。。。

  • 13
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值