数据结构(1)——单链表的插入和删除

实验目标

(1)了解和掌握线性表的逻辑结构和链式存储结构;
(2)掌握单链表的基本算法及相关的时间性能分析。

实验要求

(1)建立一个数据域存储字符串的单链表,每一个节点存储一个字符串;
(2)提供节点插入功能,在链表中不允许有重复的字符串,要求在插入节点时需要进行查重处理;
(3)提供节点删除功能,根据输入的字符串,先找到相应的结点,后删除之。

开发环境

(1)开发语言:C语言或C++语言;
(2)操作系统:Windows、Linux、Mac OS等均可;
(3)开发IDE:工具不限,推荐使用CodeBlocks和Dev C++

实验完整代码

/*****************************/
/*    链表和函数定义         */
/*****************************/

#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"ctype.h"
typedef struct node				//定义结点
{
	char data[10];				//结点的数据域为字符串
	struct node *next;			//结点的指针域
}ListNode;
typedef ListNode * LinkList;		//自定义LinkList单链表类型

LinkList CreatListR1();			//函数,用尾插入法建立带头结点的单链表
LinkList CreatList(void);			//函数,用头插入法建立带头结点的单链表
ListNode *LocateNode();			//函数,按值查找结点
void DeleteList();				//函数,删除指定值的结点
void PrintList();					//函数,打印链表中的所有值
void DeleteAll();					//函数,删除所有结点,释放内存
ListNode * AddNode();			//修改程序:增加节点。用头插法,返回头指针

/*****************************/
/*          主函数           */
/*****************************/
void main()
{
char ch[10],num[5];
LinkList head;
head=CreatList();             //用头插入法建立单链表,返回头指针
PrintList(head);              //遍历链表输出其值
printf(" Delete node (y/n):");    //输入"y"或"n"去选择是否删除结点
scanf("%s",num);
if(strcmp(num,"y")==0 || strcmp(num,"Y")==0){
		printf("Please input Delete_data:");
		scanf("%s",ch);	        //输入要删除的字符串
		DeleteList(head,ch);
		PrintList(head);
	}
	printf(" Add node ? (y/n):");   //输入"y"或"n"去选择是否增加结点
	scanf("%s",num);
	if(strcmp(num,"y")==0 || strcmp(num,"Y")==0)
	{
		head=AddNode(head);
	}

	PrintList(head);
	DeleteAll(head);            //删除所有结点,释放内存
}

/********************************/
/* 头插入法建立带头结点的单链表 */
/********************************/
LinkList CreatList(void)
{
	char ch[100];
	LinkList head, p;
	head=(LinkList)malloc(sizeof(ListNode)); 
	head->next=NULL;

	while(1)
	{
		printf("Input # to end  ");  
		printf("Please input Node_data:");
		scanf("%s",ch);           
		if(strcmp(ch,"#"))
		{       
			if(LocateNode(head,ch)==NULL) 
			{   
				strcpy(head->data,ch);
				p=(LinkList)malloc(sizeof(ListNode)); 
				p->next=head;
				head=p;
			}
		}
		else 
			break;
	}
	return head;        
}

需填写的代码

/********************************/
/* 尾插入法建立带头结点的单链表 */
/********************************/
LinkList CreatListR1(void)
{
	char ch[100];
	LinkList head;
	head=(LinkList)malloc(sizeof(ListNode)); 
	head->next=NULL;//生成头指针
	while(1)
	{
		printf("Input # to end  ");  
		printf("Please input Node_data:");
		scanf("%s",ch);           
		if(strcmp(ch,"#"))
		{       
			if(LocateNode(head,ch)==NULL) 
			{   
				head=AddNode(head,ch);//调用插入结点函数,返回插入结点之后的链表头指针			}
		}
		else 
			break;
	}
	return head;    
}

/******************************************************/
/*按值查找结点,找到则返回该结点的位置,否则返回NULL */
/*******************************************************/
ListNode *LocateNode(LinkList head, char *key)
{
	LinkList cur=head->next;//用cur来定位指针的移动,也可以直接用head
	while(cur!=NULL)
	{
		if(!strcmp(cur->data,key))//找到结点
		{
			return cur;
		}
		else
			cur=cur->next;
	}
	return NULL;
}


/********************************/
/*      修改程序:增加节点      */
/********************************/
ListNode * AddNode(LinkList head,char *key)
{
	LinkList p,cur;
	p=(LinkList)malloc(sizeof(ListNode)); 
	p->next=NULL;
	strcpy(p->data,key);//p用来存放数据
	cur=head->next;//cur用来定位尾节点
	if(LocateNode(head,key)==NULL){
		if(cur==NULL)//当链表为空的情况
		{
			head->next=p;
			return head;
		}
		while(cur->next!=NULL)//当链表不为空的情况
		{
			cur=cur->next;
		}
		cur->next=p;//往尾指针后加入新增结点
	}
	return head;
}


/******************************************/
/*    删除带头结点的单链表中的指定结点    */
/******************************************/
void DeleteList(LinkList head,char *key)
{
	LinkList p,cur,temp;
	cur=head->next;//定位指针
	p=head;//定位指针的上一个结点
	while(cur!=NULL)//判断链表是否为空
	{
		if(!strcmp(cur->data,key))//找到结点
		{
			p->next =cur->next;//cur的上一个结点与下一个结点链接在一起
			free(cur);
			return;
		}
		else
		{
			cur=cur->next;
		    p=p->next;
		}
	}
}


/******************************************/
/*               打印链表                 */
/******************************************/
void PrintList(LinkList head)
{
	head= head->next;
	while(head!=NULL)
	{
		printf("%s-->",head->data);
		head=head->next;
	}
	printf("NULL");

}

/******************************************/
/*          删除所有结点,释放空间        */
/******************************************/
void DeleteAll (LinkList head)
{
	LinkList p;//暂时存放要删除的结点
	LinkList cur=head->next;
	while(cur!=NULL)
	{
		p=cur;
		cur=cur->next;
		free(p);
	}
}


运行截图

(1) 使用前插法当加入的结点有重复时的情况

程序运行截图1

在这里插入图片描述

(2) 使用前插法当插入的结点无重复的情况时

程序运行截图2

在这里插入图片描述

(3) 使用尾插法构建链表时
程序运行截图3
在这里插入图片描述

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值