其他分享
首页 > 其他分享> > 8月24日笔记数据结构(补8)单向链表

8月24日笔记数据结构(补8)单向链表

作者:互联网

基本构造

typedef int dataType;

定义节点:struct node

创建新节点:struct node *create_new_node(dataType data)

创建新链表:struct node *create_list()

插入新节点:

        头插法:void headAdd(struct node *pnew,struct node **head)

        尾插法:void tailAdd(struct node *pnew,struct node **tail)


主函数:

        int main()

{        创建链表:

        struct node *head=create_list();

        功能:

1.打印链表节:void show_list(struct node *head)

        show_list(head);

2.更新对应节点数据:struct node *update_node(struct node *head,dataType newdata,dataType data)

        head=update_node(head,8,2);

3.删除所有对应data数据的节点:struct node *del_node(struct node *head,dataType data)

        head=del_node(head,3);

        需要free(p);释放对应删除的空间

4.在对应的data前面增加newdata节点:struct node *add_node(struct node *head,dataType newdata,dataType data)

        head=add_node(head,8,3);

5.实现排序功能:struct node *sort_list()

        sort_list();


具体代码:LinkedList.c

#include <stdio.h>
#include <stdlib.h>
//-----------------------------------
typedef int dataType;
//-----------------------------------
// 定义节点
struct node
{
	dataType data; // 数据域
	struct node *next; // 指针域,存放(指向)下一个节点的地址
};
//-----------------------------------
// 创建新节点
struct node *create_new_node(dataType data)
{
	struct node *pnew = malloc(sizeof(struct node));
	if(pnew == NULL)
		return NULL;

	// 将新数据写入到新节点
	pnew->data = data;
	pnew->next = NULL;

	return pnew;
}
//-----------------------------------
// 尾插
void tailAdd(struct node *pnew,struct node **tail)
{
	(*tail)->next = pnew; // 尾节点指向新节点
	(*tail) = pnew; // 更新尾节点
}
//-----------------------------------

// 头插
void headAdd(struct node *pnew,struct node **head)
{
	pnew->next = *head;
	(*head) = pnew;
}
//-----------------------------------
// 创建新链表
struct node *create_list()
{
	// 1.保存数据的数据
	dataType data;
	// 新节点指针,用于指向新节点
	struct node *pnew = NULL;
	// 指向首节点指针
	struct node *head = NULL;
	// 指向尾节点的指针
	struct node *tail = NULL;
	
	// 创建数据节点
	while(1)
	{
		// 输入数据
		scanf("%d",&data);
		if(data == 0) // 当输入0的时候链表创建成功
			break;
		
		// 创建新节点
		pnew = create_new_node(data);
		if(pnew == NULL)
		{
			perror("create newNode failed:");
			return NULL;
		}
		
		// 将新节点插入到链表
		if(head == NULL) // 从无到有,此时的首节点和尾节点都是pnew
		{
			head = pnew;
			tail = pnew;
		}
		else // 从少到多
		{
		#if 0// 把下面代码注释

			tailAdd(pnew,&tail);
		#else
			// 头插法
			headAdd(pnew,&head);
		#endif
		}
		
	}
		
	return head;
}
//-----------------------------------
/*
	add_node:在原来的链表head找到data,然后将newdata的节点插入到data前面
		如果查找不到data,则将newdata插入到链表的末尾
		如果要找到的数据是首节点,则将newdata切换首节点
		如果有多个相同的节点,则在第一个节点插入新节点即可
		
	struct node *add_node(struct node *head,dataType newdata,dataType data)
	参数:
		newdata : 需要插入的新节点数据
		data : 原链表中的数据,需要查找的
		
	返回值 : 成功返回链表首地址head	
*/
struct node *add_node(struct node *head,dataType newdata,dataType data)
{
	
	// 创建新节点存放newdata
	struct node *pnew = malloc(sizeof(struct node));
	if(pnew == NULL)
	{
		perror("create new data failed:");
		return NULL;
	}
	// 将新数据写入到新节点
	pnew->data = newdata;
	pnew->next = NULL;
	
	// 遍历指针,用于遍历整个链表的节点
	struct node *p = head;
	struct node *pre = NULL; // 临时保存p的前一个节点的地址
	
	while(p) // 如果p不为空,则进入循环
	{
		if(p->data == data)
		{
			break;
		}
		else // 没找到对应的节点继续往后找
		{
			pre = p;
			p = p->next;
		}
	}
	// 已经找到需要插入的节点位置
	if(p != NULL)
	{
		// 需要插入的位置为首节点
		if(p == head) // 头插法
		{
			pnew->next = head;
			head = pnew;
		}
		else // 需要插入的位置为链表的中间
		{
			pnew->next = p;
			pre->next = pnew;
		}
	}
	else // 没有找到需要插入的位置,所以只能插入原来链表的末尾
	{
		pre->next = pnew;
	}
		
	//printf("__%d__\n",__LINE__);
	return head;
}

/*
	del_node : 将head指向的链表中删除所有对应的data数据所对应的节点
*/
struct node *del_node(struct node *head,dataType data)
{
	// 遍历指针
	struct node *p = head;
	// 指向p的前一个节点
	struct node *pre = NULL;

	while(p)
	{
		if(p->data == data)// 找到需要删除的节点
		{
			if(p == head)// 需要删除的数据为首节点数据
			{
				head = head->next;
				p->next = NULL; // 断开链表
				free(p); // 释放空间
				p = head;//p重新指向新的首节点
			}
			else //删除的数据不是首节点
			{
				pre->next = p->next;
				p->next = NULL; // 断开链表
				free(p); // 释放堆空间
				p = pre->next; 
			}
		}
		else // 没有找到对应的节点,继续往下找
		{
			pre = p;
			p = p->next;
		}
	}
	
	return head;
}

/*
	update_node: 将data对应的节点数据更新为newdata数据
*/
struct node *update_node(struct node *head,dataType newdata,dataType data)
{
	struct node *p = head;
	while(p)
	{
		if(p->data == data)
		{
			p->data = newdata;
		}
		p = p->next;
	}
	
	return head;
}


// 打印链表节
void show_list(struct node *head)
{
/*	for(struct node *p = head;p != NULL;p = p->next)
	{
		printf("%d  ",p->data);
	}*/
	
	struct node *p = head;
	while(p)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	
	printf("\n");
}

/*
	sort_list : 实现排序功能
	1、创建数据节点,将首节点插入到链表
	2. 将新节点里面的数据与链表里面的节点数据进行比较
	3.如果pnew->data < p->data 就放到链表对应节点的前面
		否则就放到后面
	4.主要要考虑  : 新节点插入到首节点的情况
	
	5.遇到段错误先找到哪里出问题了,找的方式是printf("___%d_____\n",__LINE__);
	
*/
struct node *sort_list()
{
	// 定义head指针指向链表的首节点
	struct node *head = NULL;
	// 定义tial指针指向链表的尾节点
	struct node *tail = NULL;

	// 用于存放数据的数据
	dataType data;
	// 循环创建节点,将节点插入到链表
	while(1)
	{
		// 输入数据
		scanf("%d",&data);
		// 链表创建完成
		if(data == 0)
			break;
		
		// 创建新节点
		struct node *pnew = malloc(sizeof(struct node));
		if(pnew == NULL)
		{
			perror("create new node failed:");
			return NULL;
		}
		// 初始化新节点里面的数据
		pnew->data = data;
		pnew->next = NULL;
		
		//如果链表为NULL
		if(head == NULL)
		{
			head = pnew;
			tail = pnew;
		}
		else // 链表不为空
		{
			// 定义遍历指针p指向链表的首节点,用于遍历链表
			struct node *p = head;
			// 定义一个指针pre指向p的前一个节点
			struct node *pre = NULL;
			while(p)
			{
				// 如果找到对应的节点
				if(p->data > pnew->data)
				{
					break;
				}
				else // 找不到,继续找
				{
					pre = p;
					p = p->next;
				}
			}
			
			// 如果找不到对应的数据
			// 将数据插入到链表的末尾
			if(p == NULL)
			{
				tail->next = pnew;
				tail = pnew;
			}
			else // 找到了对应的数据
			{
				// 如果找到的是首节点
				if(p == head) // 头插法
				{
					pnew->next = head;
					head = pnew;
				}
				else// 中间插
				{
					pre->next = pnew;
					pnew->next = p;
				}
			}	
		}
	}
	
	return head;
}

int main()
{
	// 创建链表
	//struct node * head = create_list();
	
	// 链表排序
	struct node *head = sort_list();
	
	//head = add_node(head,8,3);
	
	// 练习 : 实现 删除节点 和 修改节点功能  时间 30分钟 
	
	// 删除节点
	//head = del_node(head,3);
	
	// 修改指定节点的数据
	//head = update_node(head,8,2);
	
	// 打印链表节点信息
	show_list(head);
	
	return 0;
}

标签:24,node,head,struct,pnew,链表,数据结构,data,节点
来源: https://blog.csdn.net/CW_qian/article/details/119898152