单向链表操作的实现(验证性实验)

单向链表操作的实现(验证性实验)

1. 需求分析

单向链表是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指向列表中的下一个结点。基本操作包括:生成链表,添加节点,返回节点,删除节点,查找结点,遍历链表。
(1) 输入的形式和输入值的范围:程序是按照数字选择对应功能的,各项功能中,除了退出程序,其他功能都要输入一个int型数字,输出的数字也为整数。
(2) 输出的形式:插入成功后显示完成;删除成功后返回完成;查找到对应位置后显示对应位置的数字,再显示完成;退出时显示链表。
(3) 程序所能达到的功能:对链表实行插入,删除,查找,遍历这些操作。
(4) 测试数据:
· 执行5次插入操作,依次输入数据1,2,3,4,5;
· 查找第一个数据;
· 删除查找的第一个数据;
· 再次查找第一个数据;
· 退出并显示链表。

2. 概要设计

  1. 为了实现程序功能,需要定义单向链表的抽象数据类型。
ADT List {
数据对象:D={ai |ai ∈ElemSet,i = 12,…,n,n>=0}
数据关系:RI={<ai-1,ai>|ai-1,ai∈D,i = 2,…,n}
typedef struct lnote{                                                        
	elemtype data;                                                        
	struct lnote *next;                                                       
}*node;
typedef struct LIST{                                                       
	node head;                                                      
	node tail;                                                             
	int len;                                                               
}list;

· 基本操作:

createlist (list &L)
操作结果:构造一个空的单向链表 
add_node(list &L,elemtype e)
	初始条件:单循环链表L存在
	操作结果:在L的第1个位置之前插入元素e
return_node(list L,elemtype,e)
	初始条件:单循环链表L存在
	操作结果:返回L的第e个节点
delete_node(list &L,int e)
初始条件:单循环链表L存在
    操作结果:删除L中值为e的一个节点
find_node(list L,elemtype n,int &e)
    初始条件:单循环链表L存在
    操作结果:返回L中值为n的一个节点,并令e等于该节点的位置。
Listtraverse(list L,int (*visit)())
    初始条件:单循环链表L存在
     操作结果:遍历L
} ADT List

3.具体代码

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

#define elemtype int                                                        
#define ERROR 0                                                             
#define OK 1                                                               

typedef struct lnote{                                            //节点结构           
	elemtype data;                                               //节点数值            
	struct lnote *next;                                                       
}*node;

typedef struct LIST{                                             //链表表结构                                       
	node head;                                                   //头指针            
	node tail;                                                   //尾指针             
	int len;                                                     //链表长度           
}list;

int visit(node p)                                                //打印节点                            
{
	if(p)                                                                    
	{
		printf("%d ",p->data);                                              
		return OK;                                                            
	}
	return ERROR;                                                           
}

void createlist(list *p);                                        //生成链表 
void add_node(list *p,elemtype num);                             //添加节点 
node return_node(list p,int num);                                //返回节点 
void delete_node(list *p,int num);                               //删除节点 
node find_node(list p,elemtype n,int &number);                   //查找结点       
void listtraver(list l,int (*visit)(node));                    //遍历链表 
 
int main()                       
{
	list test;                                                               
	createlist(&test);                                                       
	do
	{
	    printf("请选择:1.插入 2.删除 3.查找 4.退出:\n");//让用户选择                      
		int i,j,k;                                                          
		scanf("%d",&i);                                                    
		switch(i)                                                         
		{
			case 1:                                                         
				do
				{
					printf("请输入插入的值:");                             
					scanf("%d",&j);                                          
					add_node(&test,j);                                     
					printf("完成\n");                                    
				}while(0);                                                
				break;                                                 
			case 2:                                                     
				do 
				{
					printf("请输入要删除的节点的值:");            
					scanf("%d",&j);                          
					find_node(test,j,k);                 
					delete_node(&test,k);               
					printf("完成\n");                    
				}while(0);                               
				break;                                   
		    case 3:                                      
			    do
				{
					printf("请输入要查找结点的位置:");   
					scanf("%d",&j);                                        
					node test_node;                                         
					test_node=return_node(test,j);                           
					printf("第%d个结点数值为%d\n",j,test_node->data);                            
					printf("查找完成\n");                                        
				}while(0);
				break;				    
			case 4:
				printf("链表:");
				listtraver(test,visit);
				return 0;
			default:
				printf("你的输入有误!请重新输入!\n");
				break;    	
		}	
	}while(1);                                                               
	return 0;
}

void createlist(list *p)                                         //生成链表
{
	p->head = (node)malloc(sizeof(node));//为头指针指向的头节点分配储存空间 
	if(!p->head)//若分配空间失败 
	{
		exit(ERROR);//直接退出 
	}
	p->head->next = NULL;//头节点 指向null(初始条件) 
	p->tail = p->head; //初始时头尾指针指向同一个位置 
	p->len=0;//长度为0 
}
void add_node(list *p,elemtype num)                              //添加节点 
{
	//输入num 为节点数据 
	
	node q;//创建一个新的指针节点 
	q = (node)malloc(sizeof(node));//为该指针分配一个内存空间 
	if(!q)//若分配空间失败 
	{
		exit(ERROR);//直接退出 
	}
	q->data = num;//赋值 
	q->next = NULL;//next域置空 
	p->tail->next = q;//使链表的尾部节点next指向添加的节点 
	p->tail = q;//再更新链表的尾指针,指向新的节点 
	p->len++;//链表长度+1 
}
node return_node(list p,int num)                                 //返回节点
{
	//输入的num为返回节点的位置 
	
	if(p.len < num) 
	{
		//如果链表长度小于所输入的长度,直接返回空 
		return NULL;
	}
	node q;//否则创建一个q用于返回 
	q = p.head;//先让q为头节点 
	int n=1;//用于for循环 
	for(;n++ <= num;q = q->next);//然后让q往后走num次 
	return q;
}
void delete_node(list *p,int num)                                //删除节点
{
	//num为删除的节点顺序 
	if(p->len < num)
	{
		//如果链表长度小于所输入的长度,直接退出 
		exit(ERROR);
	}
	node q,r;//创建节点指针 
	q = p->head;
	int n = 1;//用于for循环 
	for(;n++ < num;q = q->next);//使q往后走num-1次,指向定点位置的前驱节点 
	r=q->next;//r指向定点位置 
	q->next=r->next;//直接跨过定点节点 
	if(num == p->len)
	{
		//如果num就是链表的长度,即删除的是尾节点 
		p->tail = q;//还需要额外更新tail的指向 
	}
	free(r);//释放r的空间(定点) 
	p->len--;//更新长度,减一 
}
node find_node(list p,elemtype n,int &number)                    //查找结点
{
	//按数据查找结点 
	node q;//创建结点指针 
	q = p.head->next;//q指向p的头节点的后一个 
	int i = 0;//用于for循环 
	for(;++i <= p.len;q = q->next)//遍历链表,查找 
	{
		if(q->data == n)
		{
			//如果发现位置 
			number = i;//则直接改变number值为位置 
			break;
		}
	}
	if(!q)//如果找不到 
	{
		number = -1;//返回 
		return NULL;
	}
	return q;
}
void listtraver(list l,int (*visit)(node))                     //遍历链表
{
	//visit为输入的函数 
	node p = l.head->next;//创建指针p指向头节点后面第一个节点 
	for(;p != NULL;p = p->next)//for循环遍历 
	{
		if(!visit(p))//进行访问,如果访问失败直接跳出 
		{
			exit(ERROR);
		}
	}
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值