链表(二)【C语言】已更新排序

写在前面的话:

  1. 编译器:DevC++
  2. 文本编辑器:Sublime Text3
  3. 本章内容:链表的增删改查、排序、反转
  4. 内容已更新:加入了另外一种排序算法

目录

1.部分结果截图:

2.代码部分


1.部分结果截图:

2.更新的排序算法 

 

//从小到大
void sort(struct node *head)
{
	
	struct node* p = head->next;

	//头节点置空
	head->next = NULL;

	struct node* tmp = p->next;

	while(p != NULL){

		//将p指向的节点插入到头节点指向的链表
		insertSortNode(head,p);

		//插完节点,将p指针指向tmp
		p = tmp;
		
		//判断p指向的是否为null
		if(p == NULL){
			break;
		} 
		
		//tmp指针据需往后移
		tmp = tmp->next;

	}
	
	show_list(head);//排序完后,显示链表 
}

void insertSortNode(struct node* head,struct node* newNode)
{

	struct node* p = head;

	//判断到尾节点
	while(p->next != NULL){

		//判断插入的元素的值是否小于新节点(new)的值
		if(p->next->n > newNode->n){
			//new节点的值较小
			newNode->next = p->next;
			p->next = newNode;
			return;
		}
		//遍历下一个节点
		p = p->next; 
	}

	//遍历完后,还没有插入到链表中,说明new新节点的值较大
	p->next = newNode;
	newNode->next = NULL;
}

3.全部代码

其中的排序算法与前面的排序不一样

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct node  //节点
{
	int n; //数据
	struct node *next; //指针
}; 

//初始化空链表
struct node *init_list() 
{   //创建一个头节点  不需要去赋值
	struct node *head=malloc(sizeof(struct node ));
	if (head!=NULL) //申请成功
	{
		head->next=NULL; //指针指向空
	}
	return head; //把这块内存的地址返回回去
}

//创建节点
struct node *create_new_node(int m) 
{
	//1.申请空间
	struct node *p=malloc(sizeof(struct node ));
	if (p!=NULL) //申请成功
	{
		p->n = m; //传什么进来 节点的数据就是什么
		p->next = NULL;
	}
	return p;//返回创建额节点
}

//插入节点【找到尾节点】
void insert_node(struct node *head,struct node *new)
{
	//定义一个临时指针指向head节点
	struct node *p = head;
	//找到最后一个节点
	while(p->next!=NULL)
	{
		p=p->next;//遍历下一个节点
	}
	//跳出循环的时候 p指向的最后一个节点
	p->next=new;  //最后一个节点的指针指向新节点
}

//遍历链表
void show_list(struct node *head)
{
	//定义一个临时指针 指向头节点的下一个 头节点没值不需要打印
	struct node *p=head->next;
	printf("[链表]"); 
	while(p!=NULL)//指向的节点不为空
	{
		printf("%d ",p->n );
		p=p->next;
	}
	printf("\n");
}

//删除
int delete_node(struct node *head,int m)
{
	//删除节点之前 找到节点的节点的前面一个节点
	struct node *p=head;
	while(p->next!=NULL)
	{
		if(p->next->n==m)
		{
			//删除节点 前一个节点的next指针指向下一个节点
			p->next = p->next->next;
			return 0;
		}
		p=p->next;
	}
	//跳出这个循环
	printf("该节点未找到!\n");
}

//判断节点是否存在
bool exist(struct node *head,int m)
{
	//定义一个临时指针 指向头节点的下一个 头节点没值不需要打印
	struct node *p=head->next;
	while(p!=NULL)//指向的节点不为空
	{
		if (p->n == m)
		{
			printf("节点已存在!\n");
			return true;
		}
		p = p->next;
	}
	return false;
}

//添加节点
void addnode(struct node *head)
{
	int m;
	while(1)
	{
		printf("[添加节点]输入你想添加节点的值(0:退出): \n");
		scanf("%d",&m);
		//判断节点是否存在
		if(exist(head,m)) 
		{
			continue;
		}
		if (m==0)
		{
			//退出程序
			break;
		}
		else if(m>0)
		{
			//创建新节点之后马上插入节点  新节点插入到链表里面去
			struct node *new = create_new_node(m);
			//插入节点 尾插法 让最后一个节点的指针指向新节点【尾插】
			insert_node(head,new);//有head指针才能找到这个链表
			//遍历链表 从head开始
			show_list(head);
		}
		else if (m<0)
		{
			printf("再次输入\n");
		}
	}
}

//删除流程
void deletenode(struct node *head)
{
	int m;
	printf("[删除节点]输入你想删除节点的值:\n");
	scanf("%d",&m);
	//删除节点 增删改查  必须前提是知道头节点  才知道链表
	delete_node(head,m);
	show_list(head);
}

//改变节点的值
void change(struct node *head)
{
	printf("[修改节点]");
	int n,m;
	printf("输入你想修改的节点:\n");
	scanf("%d",&n);
	//定义一个临时指针 指向头节点的下一个 头节点没值不需要打印
	struct node *p = head->next;
	while(p!=NULL)//指向的节点不为空
	{
		if (p->n == n) //找到2这个节点
		{
			printf("[修改节点]输入改变后的值\n");
			scanf("%d",&m);
			if(exist(head,m)) //判断节点是否存在
			{
				printf("输入的值已存在!\n");
				return;
			}
			else
			{
				p->n = m;
				return;
			}
		}
		//遍历下一个节点
		p=p->next;
	}
	printf("没有找到该节点!\n");
}

//从小到大
void sort(struct node *head)
{
	int array[25];//用于存储每一轮的最小值 
	int min = 0;//每一轮最小值 
	int temp = 0;//交换时的临时变量 
	int i,j;//循环变量 
	struct node *p = head->next;//两个指向节点的指针 
	struct node *tmp = p->next;
	head->next = NULL;//将链表置空

	for(i = 0;p != NULL && i < 25;i++)
	{
		for(j = 0;tmp != NULL;j++){
			
			if(tmp->n < p->n){
				min = tmp->n;//将最小值保存 
				temp = p->n;//交换数值,有p指针指向的是最小值 
				p->n = tmp->n;
				tmp->n = temp;
			}else{
				min = p->n;
			}			
			tmp = tmp->next;//移动tmp指针	
		}
		array[i] = min;//保存每一轮的最小值,便于后面创建节点 
		p = p->next;//p指针指向下一轮 
		if(p->next == NULL){//如果p指针到达了链表的尾部,跳出循环 
			i++;
			array[i++] = p->n;
			break;
		}
		tmp = p->next; //tmp重新初始化,新的一轮依然是p指针的下一个节点 
	}

	for(j = 0;j < i;j++){
		struct node *new1 = create_new_node(array[j]);
		insert_node(head,new1);
	}
	
	show_list(head);
	
}	

void reversed(struct node *head){

	int i,j;
	struct node* p = head->next;
	int *num = (int*)malloc(100); //只能存放25个节点 
	head->next = NULL;//链表清空

	for(i = 0;p != NULL && i < 25;i++){
		*(num+i) = p->n;
		p = p->next;
	}

	i--;
	
	printf("\n");

	for(j = i;j >= 0;j--){
		struct node *new1 = create_new_node(*(num + j));
		insert_node(head,new1);
	}

	show_list(head);

	free(num);//释放资源 
}

	
int main(int argc, char const *argv[])
{
	//1.初始化空链表  就是创建一个头节点 没有赋值
	struct node *head=init_list();
	int m;
	while(1)
	{
		printf("[输入选项]1.插入 2.删除  3.显示  4.修改  5.排序  6.反转  0.退出\n");

		scanf("%d",&m);

		if (m==0)
		{
			break;
		}

		switch(m)
		{
			case 1 : addnode(head);  break;
			case 2 : deletenode(head);break;
			case 3 : show_list(head); break;
			case 4 : change(head); break;
			case 5 : sort(head);break;
			case 6 : reversed(head);break;
			default: printf("再次输入\n");
			break;  
		}
	}
	
	return 0;
}

 完

posted @ 2022-04-10 16:56  辰梦starDream  阅读(1)  评论(0编辑  收藏  举报  来源