金明的笔记本

金明的笔记本


  金明是聚聚中学的一个学生,他们开了微机课,这个老师讲课方式很独特,每节课会讲解多个知识点但是只会讲一半,另一半让他们自己下去想,然后下一节课在开始讲另一半,这就给金明带来烦恼,金明酷爱计算机,一心想成为OI金牌选手( 做梦 ),于是每一节微机课他都非常认真,并做好笔记,但是老师每次都是讲一半,他也只能记一半,在不知道下一节课内容的情况下,他只能在每个知识点后面空一段距离,很多时候不是空多了,就是不够用,很少有恰到好处的时候。( 心里小声bb:wtm ),终于有一天老师讲了一个讲了一个叫链表的东西,什么一会前驱,一会后继的,费了好大的功夫他才把它给搞懂,并应用到了实际生活中( 从此和链表走向幸福的生活hhh
  他将他的笔记本根据链表的思想进行了以下改良:
   1.每次课记录好每个知识点
   2.在每个知识点的后面空一行
   3.下一次上课还是做好记录,并在上一次课的空行的位置写下当前页码。
咿这不就是和我们xx老师讲的单链表嘛,抽象一下如下图:

在这里插入图片描述
于是高兴的金明就想把链表分享给其他的朋友。
链表是由一个一个节点通过指向构成(看上述示意图),定义如下:

typedef int Elemtype; //定义数据类型,这样定义的好处是如果我要更改数据类型,只需要将int变成你想要的类型即可
typedef struct linknode{
	Elemtypedata;	//数据域(就是具体存储数据的)
	struct linknode *next; //指针域 存储下一个节点是谁
}

2.初始化链表

LinkList *InitList(){
	LinkList *head;
	head = (LinkList*)malloc(sizeof(LinkList));
	head -> next = NULL;
	return NULL;
}

3.插入节点(头插法)

LinkList Create_LinkList1(){
	L = NULL;						//定义L为空链表
	int x;									//设数据元素为int类型
	LNode *s;
	scanf("%d",&x);
	while(x!=-1){
		s = (LNode*)malloc(sizeof(LNode));	//申请内存
		if(s==NULL){
			printf("申请内存空间失败!");
			break;
		} 
		s->data = x;					 
		s->next = L;						//若是第一个结点,则将NULL赋给s,从第二个开始,
											//因为是从头部插入,所以s->next指向的是上一轮定义的结点 
		L = s;								//头指针指向最新的结点s 
		scanf("%d",&x);
	} 
	return L;								//返回头指针,通过头指针可以遍历该链表 
}

2.尾插法

//在表尾插入结点
LinkList Create_LinkList2(){
	L = NULL;
	LNode *s;	//定义结点 
	LNode *r;	//定义尾指针,永远指向最后一个结点 
	int x;
	s = (LNode*)malloc(sizeof(LNode));	//定义头结点,申请内存
	if(s==NULL){
		printf("申请内存空间失败!");
	}
	s->next = NULL;
	L = s;	//头指针指向头结点 
	r = s; 	//尾指针指向头结点		注:此时链表里面没有数据结点
	scanf("%d",&x);
	while(x!=-1){
		s = (LNode*)malloc(sizeof(LNode));
		if(s==NULL){
			printf("申请内存空间失败!");
			break;
		}	
		s->data = x;
		s->next = NULL;
		r->next = s;	//将尾结点的next指向最新的结点 
		r = s;			//尾指针指向最新的结点 
		scanf("%d",&x);
	}
	return L; 
}

4.插入操作

//插入(前插结点)(带头结点)(失败返回0,成功返回1) 
int Insert_LinkList(LinkList L,int i,int x){
	LNode *p,*s;
	p = Get_LinkList(L,i-1);	//获取第i-1个结点
	if(p==NULL){
		printf("参数i错误!\n");
		return 0; 
	}
	else{
		s = (LNode*)malloc(sizeof(LNode));	//申请、填装结点 
		if(s==NULL){
			printf("申请内存空间失败!");
			return 0;
		}
		s->data = x;
		s->next = p->next;
		p->next = s;
		return 1; 		
	} 
}

5.删除操作

//删除结点
int Delete_LinkList(LinkList L,int i){
	LinkList p,s;
	p = Get_LinkList(L,i-1);	//获取第i-1个节点
	if(p==NULL){
		printf("第i-1个结点不存在\n");
		return -1; 
	}else if(p->next==NULL){
		printf("第i个结点不存在");
		return 0;	
	}else{
		s = p->next;
		p->next = s->next;
		free(s);	//释放*s; 
		return 1; 
	} 
}

完整代码如下:

#include <stdio.h>
#include <malloc.h>
typedef int Elemtype;	//Elemtype定义为int型 
typedef struct lnode{	//结点 
	Elemtype data;		//数据域 
	struct lnode *next;	//指针域 
}LNode,*LinkList;		//LNode是结点类型,LinkList是指向LNode类型结点的指针类型 
LinkList L;			//定义头指针变量 
 
//在表头插入结点 
LinkList Create_LinkList1(){
	L = NULL;						//定义L为空链表
	int x;									//设数据元素为int类型
	LNode *s;
	scanf("%d",&x);
	while(x!=-1){
		s = (LNode*)malloc(sizeof(LNode));	//申请内存
		if(s==NULL){
			printf("申请内存空间失败!");
			break;
		} 
		s->data = x;					 
		s->next = L;						//若是第一个结点,则将NULL赋给s,从第二个开始,
											//因为是从头部插入,所以s->next指向的是上一轮定义的结点 
		L = s;								//头指针指向最新的结点s 
		scanf("%d",&x);
	} 
	return L;								//返回头指针,通过头指针可以遍历该链表 
} 
 
//在表尾插入结点
LinkList Create_LinkList2(){
	L = NULL;
	LNode *s;	//定义结点 
	LNode *r;	//定义尾指针,永远指向最后一个结点 
	int x;
	s = (LNode*)malloc(sizeof(LNode));	//定义头结点,申请内存
	if(s==NULL){
		printf("申请内存空间失败!");
	}
	s->next = NULL;
	L = s;	//头指针指向头结点 
	r = s; 	//尾指针指向头结点		注:此时链表里面没有数据结点
	scanf("%d",&x);
	while(x!=-1){
		s = (LNode*)malloc(sizeof(LNode));
		if(s==NULL){
			printf("申请内存空间失败!");
			break;
		}	
		s->data = x;
		s->next = NULL;
		r->next = s;	//将尾结点的next指向最新的结点 
		r = s;			//尾指针指向最新的结点 
		scanf("%d",&x);
	}
	return L; 
}
 
//获取链表长度(带头结点)
int Length_LinkList1(LinkList L){
	LNode *p = L;
	int j=0;
	while(p->next){
		p = p->next;
		j++;
	}
	return j; 
}
 
//获取链表长度(不带头结点)
int Length_LinkList2(LinkList L){
	LNode *p = L;			//非空表下指向的就是第一个结点 
	int j=0;
	while(p){
		j++;
		p = p->next;
	}
	return j; 
}
 
//按序号查找单链表中的第i个元素结点,找到返回指针,否则返回空 (带头结点) 
LNode *Get_LinkList(LinkList L,int i){
	LNode *p = L;
	int j=0;
	while(j<i&&p->next!=NULL){
		p = p->next;
		j++;
	}
	if(j==i)
		return p;
	else
		return NULL;
} 
 
// 按值查找(带头结点)
 LNode *Locate_LinkList(LinkList L,int x){
	LNode *p = L->next;
	while(p!=NULL&&p->data!=x){
		p = p->next;
	}
	return p;
} 
 
//插入(前插结点)(带头结点)(失败返回0,成功返回1) 
int Insert_LinkList(LinkList L,int i,int x){
	LNode *p,*s;
	p = Get_LinkList(L,i-1);	//获取第i-1个结点
	if(p==NULL){
		printf("参数i错误!\n");
		return 0; 
	}
	else{
		s = (LNode*)malloc(sizeof(LNode));	//申请、填装结点 
		if(s==NULL){
			printf("申请内存空间失败!");
			return 0;
		}
		s->data = x;
		s->next = p->next;
		p->next = s;
		return 1; 		
	} 
 
}
 
//删除结点
int Delete_LinkList(LinkList L,int i){
	LinkList p,s;
	p = Get_LinkList(L,i-1);	//获取第i-1个节点
	if(p==NULL){
		printf("第i-1个结点不存在\n");
		return -1; 
	}else if(p->next==NULL){
		printf("第i个结点不存在");
		return 0;	
	}else{
		s = p->next;
		p->next = s->next;
		free(s);	//释放*s; 
		return 1; 
	} 
}
 
//遍历链表
void Find(LinkList L){
	LNode *p = L->next;
	int i=0;
	while(p){
		i++;
		printf("---->|Node%d->data:%d|\n",i,p->data);
		p = p->next;
	} 
} 
 
void list(){
	printf("This is a Singly Linked List.\n------------------------------------------\nPlease press the button:\n");
	printf("Button 1 ---> Create_LinkList()\n");				//创建单链表 (带头结点、表尾插入)
	printf("Button 2 ---> Length_LinkList(L)\n");				//获取链表长度
	printf("Button 3 ---> Get_LinkList(L,i)\n");				//按序号查找 
	printf("Button 4 ---> Locate_LinkList(L,x)\n");				//按值查找 
	printf("Button 5 ---> Insert_LinkList(L,i,number)\n");		//插入结点 
	printf("Button 6 ---> Delete_LinkList(L,i)\n");				//删除结点 
	printf("Button 7 ---> Find(L)\n");							//遍历链表 
	printf("Button 8 ---> Exit the program\n-----------------------------------\n");					//退出程序 
}
 
 
int main(){
	list();
	while(true){
	printf("Choose Button: ");	
		int n;
		int flag =1;
		int length,i,number,item;//item用于Insert插入和Detele删除的返回数据 
		LNode *p;
		scanf("%d",&n);
		switch(n){
			case 1:
				printf("If you enter '-1',the list is created\n");			//若输入-1,则表示链表元素创建完成 
				L = Create_LinkList2();
				printf("--------------------------------------------------------\n");
			break;
				
			case 2:
				if(L==NULL)
				{	
					printf("Sorry!Wrong!\n-------------------------------------------------\n");
					break;
				}
				length = Length_LinkList1(L);
				printf("The Singly Link List length is: %d\n-------------------------------------\n",length);		//单链表的长度为: 
			break;	
 
			case 3:
				printf("Please enter you want to find serial number-->i:  ");//请输入你想查找的序号 
				scanf("%d",&i);
				if(L==NULL)
				{	
					printf("Sorry!Wrong!\n-------------------------------------------------\n");
					break;
				}
				p =Get_LinkList(L,i);
				if(p==NULL){
					printf("Sorry!Wrong!\n----------------------------------------------\n");			//第i个位置为NULL,错误 
				}else{
					printf("Successsful!The Node data is:%d\n--------------------------------------\n",p->data);//不为NULL,查找成功,输出该结点数据域 
				} 	
			break;
				
			case 4:
				printf("Please enter you want to find number:  ");
				scanf("%d",&number);
				if(L==NULL)
				{	
					printf("Sorry!Wrong!\n-------------------------------------------------\n");
					break;
				}
				p = Locate_LinkList(L,number);
				if(p==NULL)
					printf("Sorry!Wrong!\n-------------------------------------------------\n");			//第i个位置为NULL,错误 
				else
					printf("Successsful!The Node data is:%d\n-------------------------------------------\n",p->data);//不为NULL,查找成功,输出该结点数据域  
			break;
				
			case 5:							//插入结点 
				printf("Please enter i and number:  ");
				scanf("%d%d",&i,&number);
				item = Insert_LinkList(L,i,number);
				if(item==0)
					printf("Insert failed-----------------------------------------------------\n");
				else
					printf("Insert successful--------------------------------------------------------\n");
			break;
				
			case 6:									//删除结点 
				printf("Please enter i:  ");
				scanf("%d",&i);
				item = Delete_LinkList(L,i);
				if(item==0 || item==-1)
					printf("Delete failed----------------------------------------------------------\n");
				else
					printf("Delete successful-------------------------------------------------------------\n");
			break;
							
			case 7:
				printf("Traverse Singly Linked List:\n");		//遍历该单链表 
				if(L==NULL)
				{	
					printf("Sorry!Wrong!\n-------------------------------------------------\n");
					break;
				}
				Find(L); 
				printf("-------------------------------------------------------------------------\n");
			break;
			
			case 8:
				printf("Exit the program successful!\n");
				flag = -1;
			break;
						 
			default:
				printf("Sorry!You can't do that!\n");
				flag = -1;
			break;	
		}
		if(flag==-1)
		break;
	}
 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值