链表合并,删除节点,插入节点

题目描述:输入两个按从小到大排序的链表,然后进行合并成新链表,并且顺序保持从小到大。然后删除新链表中指定值的结点,然后插入指定值的新节点。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>

typedef struct node{
	int data;
	struct node *next;
}Node, *pNode;

pNode create_list(int n){//头插法建立 
	int i; 
	pNode head = (pNode)malloc(sizeof(Node));
	pNode rear = head;
	if(head == NULL){
		printf("存储空间分配失败!\n");
		exit(-1);
	}
	for(i=0; i<n; i++){
		pNode pNew = (pNode)malloc(sizeof(Node));
		if(pNew == NULL){
			printf("存储空间分配失败!\n");
			exit(-1);
		}
		printf("请输入值:");
		scanf("%d", &(pNew->data));
		rear->next = pNew;
		rear = pNew;
		rear->next = NULL; 
	} 
	return head;
}

void traverse_list(pNode head){
	pNode p = head->next;
	while(p !=NULL){
		printf("%d ", p->data);
		p = p->next;
	} 
}

pNode merge_list(pNode h1, pNode h2){
	pNode q, head; //q的作用是按从小到大依次链接新链表的每个节点; 
	q = head = h1;
	h1 = h1->next;
	h2 = h2->next;
	while(h1 && h2){
		if(h1->data <= h2->data){
			q->next = h1;
			q = q->next;
			h1 = h1->next;
		}
		else{
			q->next = h2;
			q = q->next;
			h2 = h2->next;
		}
	}
	if(h1)//跳出while,必定至少有一个链表为空,当链表h1不为空,h2为空时,将h1剩余节点插入新链表尾部 
		q->next = h1;
	if(h2)//跳出while,必定至少有一个链表为空,当链表h2不为空,h1为空时,将h2剩余节点插入新链表尾部 
		q->next = h2;	
	return head;
}

pNode delete_list(pNode head, int x){
	pNode p, q;
	p = head; q = p->next;//p指向要删除节点的前驱 ,q指向要删除节点 
	int count = 0;
	while(q != NULL){
		if(q->data == x){
			p->next = q->next;
			free(q);
			q = p->next;
			count++; //count记录删除了的节点个数 
		}
		else{
			p = q;
			q = p->next;
		}
	}
	if(!count){
		printf("不存在该节点!\n");
		return NULL;
	}	
	return head;
}

pNode insert_list(pNode head, int x){
	pNode pNew = (pNode)malloc(sizeof(Node));
	if(pNew == NULL){
		printf("存储空间分配失败!\n");
		exit(-1);
	}
	pNew->data = x;
	pNew->next = NULL;	
	pNode p = head;
	while(p->next != NULL){//p指向要插入位置的前一个 
		if(x <= p->next->data){//找到位置,插入 
			pNew->next = p->next;
			p->next = pNew;
			break;//注意不要忘记这步,否则影响后面if(p->next == NULL) 的判断 
		}	
		else{
			p = p->next;
		}
	}
	if(p->next == NULL){//p走到最后一个节点,说明要插入的节点大于原链表所有节点值,这时插入最尾部即可 
		p->next = pNew; 
		pNew->next = NULL;
	}
	return head;
}

int main(){
	int n1, n2, x1, x2;
	
	printf("请输入第一个链表节点个数n1:");
	scanf("%d", &n1);
	pNode h1 = create_list(n1);
	traverse_list(h1);
	printf("\n");
	
	printf("请输入第二个链表节点个数n2:");
	scanf("%d", &n2);
	pNode h2 = create_list(n2);
	traverse_list(h2);
	printf("\n");
	
	pNode h3 = merge_list(h1, h2);
	printf("合并后:\n"); 
	traverse_list(h3);
	printf("\n");
	
	printf("请输入要删除的数x1:\n");
	scanf("%d", &x1);
	pNode h4 = delete_list(h3, x1);
	if(h4 == NULL)
		printf("不存在该节点!\n");
	else{
		printf("删除后:\n"); 
		traverse_list(h4);
		printf("\n"); 
	} 

	printf("请输入要插入的数x2:\n");
	scanf("%d", &x2);
	pNode h5 = insert_list(h4, x2);
	printf("插入后:\n"); 
	traverse_list(h5);
	printf("\n");
	 
	return 0;
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值