栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构02:单链表

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构02:单链表

一.各个函数的代码

1)链表的创建

typedef struct LinkNode
{
	char data;  //数据域 
	struct LinkNode *next; //指针域 
} LNode,*LinkList,*NodePtr; //取不同的名字利于代码可读性 并且如果在此申明了*号,后续引用时不用写*只写NodePtr和LinkList也是指针变量 

2)链表的初始化

LinkList initLinkList() //链表的初始化 
{
	NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode)); //像这样子结合上面的命名与注释就完全不成问题了
	tempHeader->data = '';
	tempHeader->next = NULL;//将头指针所指向的数据域和结构域全部弄成空;方便后续操作
	
	return tempHeader;//返回头指针所指向的地址就成功创建了一个空链表 
}

3)打印链表

void printLinkList(NodePtr paraHeader)
{
	NodePtr p =  paraHeader->next ; 
	while(p != NULL)
	{
		printf("%c",p->data);
		p = p->next;
	}
	printf("rn");
}

4)尾插元素(老师的代码)

void appendElement(NodePtr paraHeader,char paraChar)
{
	NodePtr p,q;
	q = (NodePtr)malloc(sizeof(LNode));
	//****一般对于链表的操作都需要重新给两个指针,一个分配空间存数据,一个用来跟踪;
	q->data = paraChar;
	q->next = NULL;
	
	p = paraHeader;
	while(p->next != NULL)
	{
		p = p->next;//添加就追踪到指向最后一个位置的指针 
	}
	p->next = q;
}

5)头插元素

void appendElement2(NodePtr paraHeader,char paraChar)//从头部插入元素
{
	NodePtr p,q;
	q = (NodePtr)malloc(sizeof(LNode));	
	q->data = paraChar;
	p = paraHeader;
	
	if(p->next == NULL) //插入第一个元素时情况特殊,需要if 
	{
		p->next = q;
		q->next = NULL; 
		return;
	}
	q->next = p->next;
	p->next = q;
	
}

6)删除指定值的元素(老师的代码)

void deleteElement(NodePtr paraHeader,char paraChar)
{
	NodePtr p,q;
	p = paraHeader;
	while((p->next != NULL) && (p->next->data != paraChar))
	{
		p = p->next;//删除追踪到指向该数据所在位置上一个位置的指针 
	}
	if(p->next == NULL)
	{
		printf("Cannot delete %crn",paraChar);
		return ; 
	}
	
		q = p->next;
		p->next = p->next->next;
		free(q);
}

7)删除指定位置的元素

void deleteElement2(NodePtr paraHeader,int paraPosition)//删除指定位置的元素 
{
	NodePtr p,q;
	int i;
	p = paraHeader;
	if(paraPosition < 0)
	{
		printf("无效的位置rn");
		return; 
	}
	for(i = 0;i < paraPosition;i ++)
	{
	 	p = p->next;
	 	
	 	if(p == NULL)
	 	{
	 		printf("位置太远了,无效的位置rn");
			return; 
		}
	}
	
	q = p->next;
	p->next = p->next->next;
	free(q);	
} 

8)在指定位置插入元素(老师的代码)

void insertElement(NodePtr paraHeader,char paraChar,int paraPosition)
{
	NodePtr p,q;
	q = (NodePtr)malloc(sizeof(LNode));
	p = paraHeader;
	
	int i;
	for(i = 0;i < paraPosition;i ++)
	{
		p = p->next ;//插入追踪到指向要插入位置前一个位置的指针 
		if(p == NULL)
		{
			printf("The position %d is beyond the scope of the list.",paraPosition);
			return;
		}
	}
	q = (NodePtr)malloc(sizeof(LNode));
	q->data = paraChar;
	
	printf("linkingrn");
	q->next = p->next ;
	p->next = q;	
}

9)在指定值后面插入元素

void insertElement2(NodePtr paraHeader,char paraChar,char paraPositionChar)//该函数在某个字符后面插入,而不是从某个位置插入;
{
	NodePtr p,q;
	q = (NodePtr)malloc(sizeof(LNode));
	p = paraHeader;
	while(p->data != paraPositionChar)
	{
		p = p->next;
		if(p == NULL)
		{
			printf("我们没有找到目标字母,无法插入!rn");
			return; 
		}	
	}
	
	q->data = paraChar;
	printf("linkingrn");
	
	q->next = p->next;
	p->next = q;
}

10)测试代码

void appendInsertDeleteTest()
{
	// 初始化测试 
	LinkList tempList = initLinkList();
	printLinkList(tempList);

	//添加2测试 (头部) 
	appendElement2(tempList, 'Q');//第一个位置特殊情况测试 
	appendElement2(tempList, 'A');//正常测试 
	appendElement2(tempList, 'D');
	printLinkList(tempList);
	
	// 添加测试 (尾部) 
	appendElement(tempList, 'H');
	appendElement(tempList, 'e');
	appendElement(tempList, 'l');
	appendElement(tempList, 'l');
	appendElement(tempList, 'o');
	appendElement(tempList, '!');
	printLinkList(tempList);

	// 删除测试 
	deleteElement(tempList, 'e');
	deleteElement(tempList, 'a');
	deleteElement(tempList, 'o');
	printLinkList(tempList);

	// 插入1测试 
	insertElement(tempList, 'o', 1);
	printLinkList(tempList);
	
	//插入2测试 
	insertElement2(tempList, 'a', 'w');//第一个是找不到目标 
	printLinkList(tempList);
	insertElement2(tempList, 'p', 'H');//边界测试第一个字符的后面 
	printLinkList(tempList);
	insertElement2(tempList, 'x', '!');//边界测试最后一个字符的后面
	printLinkList(tempList);
	
	//删除2测试 
	deleteElement2(tempList,20);//范围之外 
	printLinkList(tempList);
	deleteElement2(tempList,0);//边界测试第一个字符
	printLinkList(tempList);
	deleteElement2(tempList,5);//边界测试最后一个字符 
	printLinkList(tempList);
	
}

二.插入和删除的简要图示


明白这两个,其他所有的插入添加和删除都大同小异

三.全部代码

#include 
#include 

typedef struct LinkNode
{
	char data;  //数据域 
	struct LinkNode *next; //指针域 
} LNode,*LinkList,*NodePtr; //取不同的名字利于代码可读性 并且如果在此申明了*号,后续引用时不用写*只写NodePtr和LinkList也是指针变量 

LinkList initLinkList() //链表的初始化 
{
	NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode)); //第一个括号里面要指针,第二个要非指针,像这样子结合上面的命名与注释就完全不成问题了
	tempHeader->data = '';
	tempHeader->next = NULL;//将头指针所指向的数据域和结构域全部弄成空;方便后续操作
	
	return tempHeader;//返回头指针所指向的地址就成功创建了一个空链表 
} 

void printLinkList(NodePtr paraHeader)
{
	NodePtr p =  paraHeader->next ; 
	while(p != NULL)
	{
		printf("%c",p->data);
		p = p->next;
	}
	printf("rn");
}

void appendElement(NodePtr paraHeader,char paraChar)
{
	NodePtr p,q;
	q = (NodePtr)malloc(sizeof(LNode));
	//****一般对于链表的操作都需要重新给两个指针,一个分配空间存数据,一个用来跟踪;
	q->data = paraChar;
	q->next = NULL;
	
	p = paraHeader;
	while(p->next != NULL)
	{
		p = p->next;//添加就追踪到指向最后一个位置的指针 
	}
	p->next = q;
}

void appendElement2(NodePtr paraHeader,char paraChar)//从头部插入元素
{
	NodePtr p,q;
	q = (NodePtr)malloc(sizeof(LNode));	
	q->data = paraChar;
	p = paraHeader;
	
	if(p->next == NULL) //插入第一个元素时情况特殊,需要if 
	{
		p->next = q;
		q->next = NULL; 
		return;
	}
	q->next = p->next;
	p->next = q;
	
} 

void deleteElement(NodePtr paraHeader,char paraChar)
{
	NodePtr p,q;
	p = paraHeader;
	while((p->next != NULL) && (p->next->data != paraChar))
	{
		p = p->next;//删除追踪到指向该数据所在位置上一个位置的指针 
	}
	if(p->next == NULL)
	{
		printf("Cannot delete %crn",paraChar);
		return ; 
	}
	
		q = p->next;
		p->next = p->next->next;
		free(q);
}

void deleteElement2(NodePtr paraHeader,int paraPosition)//删除指定位置的元素 
{
	NodePtr p,q;
	int i;
	p = paraHeader;
	if(paraPosition < 0)
	{
		printf("无效的位置rn");
		return; 
	}
	for(i = 0;i < paraPosition;i ++)
	{
	 	p = p->next;
	 	
	 	if(p == NULL)
	 	{
	 		printf("位置太远了,无效的位置rn");
			return; 
		}
	}
	
	q = p->next;
	p->next = p->next->next;
	free(q);	
} 

void insertElement(NodePtr paraHeader,char paraChar,int paraPosition)
{
	NodePtr p,q;
	q = (NodePtr)malloc(sizeof(LNode));
	p = paraHeader;
	
	int i;
	for(i = 0;i < paraPosition;i ++)
	{
		p = p->next ;//插入追踪到指向要插入位置前一个位置的指针 
		if(p == NULL)
		{
			printf("The position %d is beyond the scope of the list.",paraPosition);
			return;
		}
	}
	q = (NodePtr)malloc(sizeof(LNode));
	q->data = paraChar;
	
	printf("linkingrn");
	q->next = p->next ;
	p->next = q;	
}

void insertElement2(NodePtr paraHeader,char paraChar,char paraPositionChar)//该函数在某个字符后面插入,而不是从某个位置插入;
{
	NodePtr p,q;
	q = (NodePtr)malloc(sizeof(LNode));
	p = paraHeader;
	while(p->data != paraPositionChar)
	{
		p = p->next;
		if(p == NULL)
		{
			printf("我们没有找到目标字母,无法插入!rn");
			return; 
		}	
	}
	
	q->data = paraChar;
	printf("linkingrn");
	
	q->next = p->next;
	p->next = q;
} 

void appendInsertDeleteTest()
{
	// 初始化测试 
	LinkList tempList = initLinkList();
	printLinkList(tempList);

	//添加2测试 (头部) 
	appendElement2(tempList, 'Q');//第一个位置特殊情况测试 
	appendElement2(tempList, 'A');//正常测试 
	appendElement2(tempList, 'D');
	printLinkList(tempList);
	
	// 添加测试 (尾部) 
	appendElement(tempList, 'H');
	appendElement(tempList, 'e');
	appendElement(tempList, 'l');
	appendElement(tempList, 'l');
	appendElement(tempList, 'o');
	appendElement(tempList, '!');
	printLinkList(tempList);

	// 删除测试 
	deleteElement(tempList, 'e');
	deleteElement(tempList, 'a');
	deleteElement(tempList, 'o');
	printLinkList(tempList);

	// 插入1测试 
	insertElement(tempList, 'o', 1);
	printLinkList(tempList);
	
	//插入2测试 
	insertElement2(tempList, 'a', 'w');//第一个是找不到目标 
	printLinkList(tempList);
	insertElement2(tempList, 'p', 'H');//边界测试第一个字符的后面 
	printLinkList(tempList);
	insertElement2(tempList, 'x', '!');//边界测试最后一个字符的后面
	printLinkList(tempList);
	
	//删除2测试 
	deleteElement2(tempList,20);//范围之外 
	printLinkList(tempList);
	deleteElement2(tempList,0);//边界测试第一个字符
	printLinkList(tempList);
	deleteElement2(tempList,5);//边界测试最后一个字符 
	printLinkList(tempList);
	
	
}

int main()
{
	appendInsertDeleteTest();
}


四.代码运行结果

如有错误,敬请大佬们指正!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/850844.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号