【数据结构与算法 1】(单链表)快慢指针实现查找单链表中间数据

本程序为单链表程序实现,包含

  1. 创建链表
  2. 查看链表
  3. 链表长度
  4. 插入元素
  5. 删除指定元素
  6. 中间节点数据(使用快慢指针实现)
  7. 删除链表

运行示例如下:
在这里插入图片描述


程序代码如下:

// 单链表实现方式 
// 利用快慢指针,查找单链表的中间节点 

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>


// 定义单链表结构体,并构建结构对象 ListNode 和 指向结构的指针LinkList 
typedef struct ListNode{
	int data;
	struct ListNode *next; 
}ListNode, *LinkList;

// 创建链表 
void Create_List(LinkList head)
{
	int temp;
	LinkList p;
	
	printf("请输入节点值,以任意非数字结尾:\n");
	// 刷新输入缓冲区 
	fflush(stdin);
	
	// 根据输入的值,循环动态创建链表,直到非数字结束 
	while( scanf("%d", &temp) == 1){
		
		//printf("temp = %d\n", temp);
		p = (LinkList) malloc(sizeof(ListNode));
		p->data = temp;
		
		// 头插法: 
		p->next = head->next;
		head->next = p;

		//  刷新输入缓冲区
		fflush(stdin);
	}
} 

// 清空链表
void Delete_List(LinkList head){
	LinkList temp;
	int i=0; 
	
	while(head->next != NULL){
		temp = head->next;
		head->next = temp->next;
		
		printf("删除链表数据 [%d] (%d) temp=%p\n", i, temp->data,temp); 
		free(temp);
		
		i++;
	}
}

int Get_List_Len(LinkList head)
{
	LinkList temp;
	int i = 0;
	
	temp = head->next;
	while(temp != NULL){
		i++;
		temp = temp->next; 
	}
	return i;
}

void Print_List(LinkList head)
{
	LinkList p;
	int i = 0;
	
	p = head->next;
	
	if(p == NULL){ 
		printf("链表为空\n");
		return; 
	}
	
	printf("链表的数据为:\n");
	while(p != NULL){
 		printf("[%d]: %d \t", i, p->data);
 		i++;
 		p = p->next;
 		
 		if( (i%5) == 0)
 			printf("\n");
	}
	printf("\n");
} 


void Get_Mid_ListNode(LinkList head)
{
	LinkList end_p, mid_p;

	if(head->next == NULL){ 
		printf("链表为空\n");
		return; 
	}
		
	end_p = head;
	mid_p = head;
	
	while(end_p->next != NULL && end_p->next->next != NULL){
		end_p = end_p->next->next;
		mid_p = mid_p->next;
	}
	printf("中间节点的值为(%d) , 末尾中间节点的值为(%d) \n", mid_p->data, end_p->data);
} 


void Insert_data(LinkList head)
{
	int i=0, max_len=0, num=0, data=0;
	LinkList p=head ,tmp_p;
	
	if(p->next == NULL){ 
		printf("链表为空\n");
		return; 
	}
	
	while( scanf("%d", &num) != 1 || num == 0){
		printf("\n当前输入值非法,请输入正确的数字\n\n");
		fflush(stdin);
	}
	
	max_len = Get_List_Len(head);
	if(num > max_len+1)
	{
		printf("插入节点位置不对(%d),长度超出范围(%d)\n", num, max_len);
		return;	
	}
	// 开始在单链表中查找对应的位置 及 值 
	while( i != (num - 1)){
		i++;
		p = p->next;
		//printf("debug---i(%d) num-1(%d) data(%d)---\n", i,num-1,  p->data);
	}
	
	printf("插入节点位置的值为 [%d]%d ,开始插入数据\n", i, p->data);
	while( scanf("%d", &data) != 1){
		printf("\n当前输入值非法,请输入正确的数据\n\n");
		fflush(stdin);
	}
	tmp_p = (LinkList)malloc(sizeof(ListNode));
	tmp_p->data = data;
	
	tmp_p->next = p->next;
	p->next = tmp_p;
	
	printf("插入数据完成\n");
} 

void Delete_data(LinkList head)
{
	int i=0, num=0, max_len=0;
	LinkList p=head->next , pre_p=head,tmp_p;
	
	if(p == NULL){ 
		printf("链表为空\n");
		return; 
	}
	max_len = Get_List_Len(head);
	printf("您要删除第几个数据,当前数据长度为%d\n", max_len);
	while(scanf("%d", &num) != 1 || num > max_len){
		printf("\n当前输入值非法,请输入正确的数据\n\n");
		fflush(stdin);
	}
	
	while(i != (num-1)){
		pre_p = p; 
		p = p->next;
		i++;
	}
	printf("要删除的节点位置值为 [%d]%d\n", i, p->data);
	tmp_p = p;
	pre_p->next = p->next;
	free(tmp_p);
}



int main(void)
{
	int cmd = 0;
	
	LinkList head;
	
	head = (LinkList)malloc(sizeof(ListNode));
	head->next = NULL;
	
	while(1){
		printf(	"\n"
		    	"1.创建链表\n"
				"2.查看链表\n"
				"3.链表长度\n"
				"4.插入元素\n"
				"5.删除指定元素\n"
				"6.中间节点数据\n"
				"7.删除链表\n"
				"0.退出\n"
				"请输入命令: ");
				
		while( scanf("%d", &cmd) != 1){
			printf("\n当前输入非法,请输入正确的命令\n\n");
			fflush(stdin);
		}
		
		printf("\n您输入的命令为 %d \n", cmd);

		// 检查是否是退出操作 
		if(cmd == 0){ 
			printf("程序退出,谢谢!!! \n\n");
			break;
		} 
		 
		switch(cmd){
			case 1:		// 创建链表
				Create_List(head);
				break;
			case 2:		// 查看链表 
				Print_List(head);
				break;
			case 3:		// 链表长度 
				printf("\n链表长度为 %d \n", Get_List_Len(head));
				break;
			case 4:		// 插入元素 
				Insert_data(head);
				break;
			case 5:		// 删除元素 
				Delete_data(head);
				break;
			case 6:		// 中间节点数据 
				Get_Mid_ListNode(head);
				break;
			case 7:		// 删除链表 
				Delete_List(head);
				break;
			default:
				printf("\n当前为不支持的命令,请重新输入正确的命令\n", cmd);
				break;
		}
		
		// 清空输入输出缓冲区 
		fflush(stdin); 
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章