王道数据结构第二章C语言题解 2.7-2.10

? 2.7

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//在带头节点的单链表中,删除所有值为x的结点,并释放其空间

typedef struct Node
{
	int data;
	struct Node* next;
}Node;



//创建一个带头节点的链表 返回链表的头指针
Node* Init_List()
{
	Node* head = (Node*)malloc(sizeof(Node));
	assert(head);

	int first,size;

	printf("please enter list sizes: ");
	scanf("%d",&size);


	head->data = 0;
	head->next = NULL;

	//采用尾插法,构建链表
	//则需要构建一个链表的尾指针
	Node* tail = head;

	for(int i = 0; i < size ; i++)
	{
		Node* new = (Node*)malloc(sizeof(Node));
		assert(new);

		scanf("%d",&first);
		new -> data = first;
		tail-> next = new;
		new -> next = NULL;
		tail = tail->next;

	}

	return head;

}


void delete_value_x (Node* head,int a,int b)
{
	Node* p = head;
	Node* q = p;    //指向要删除节点的前驱
	p = p->next;

	while(p)
	{
		if(p->data >= a && p->data <= b) //下面是普通的删除操作
		{
			Node* save;
			save = p;    //保存节点,好释放
			q->next = p->next;
			p = p->next;
			free(save);
		}
		else
		{
			q = p;
			p = p->next;
		}
	}



}


void print_list(Node* head)
{
	Node* p ;
	p = head->next;

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

	printf("\n");

}


int main(int argc, char const *argv[])
{
	Node* list = Init_List();

	printf("please enter the area you want to delete:");
	int delete_head,delete_end;
	scanf("%d",&delete_head);
	scanf("%d",&delete_end);


	delete_value_x(list,delete_head,delete_end);

	print_list(list);
	

	return 0;
}

在这里插入图片描述

? 2.8

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define MAX_SIZE 100

//在带头节点的单链表中,删除所有值为x的结点,并释放其空间

typedef struct Node
{
	int data;
	struct Node* next;
}Node;



//创建一个带头节点的链表 返回链表的头指针
Node* Init_List()
{
	Node* head = (Node*)malloc(sizeof(Node));
	assert(head);

	int first,size;

	printf("please enter list sizes: ");
	scanf("%d",&size);


	head->data = 0;
	head->next = NULL;

	//采用尾插法,构建链表
	//则需要构建一个链表的尾指针
	Node* tail = head;

	for(int i = 0; i < size ; i++)
	{
		Node* new = (Node*)malloc(sizeof(Node));
		assert(new);

		scanf("%d",&first);
		new -> data = first;
		tail-> next = new;
		new -> next = NULL;
		tail = tail->next;

	}

	return head;

}


//我能想到的第一个就是每找一个,就在另一个链表中遍历一下
//时间复杂度为o(n^2)
//第二种方法就是存到数组中 把这个元素都存到一个数组中 (链表里面的值不能大于MAX_SIZE)
//我用第二种算法实现,这样时间复杂度只有O(n)
//因为只要找出,所以输出正确即可


//我觉得这个算法,比两次扫描要好,就是牺牲了空间来换取时间,另外对链表内存的元素也是有要求的
void jiaoji(Node* head1,Node* head2)
{

	//存到数组中
	int value;
	int save_array1[MAX_SIZE] = {0};
	int save_array2[MAX_SIZE] = {0};

	Node* p = head1->next;
	Node* q = head2->next;

	while(p != NULL)
	{
		value = p->data;
		save_array1[value] ++;
		p = p->next;
	}

	while(q != NULL)
	{
		value = q->data;
		save_array2[value] ++;
		q = q->next;
	}

	//存完毕 然后查找数组下标等于2的,即为交集
	//(有一个问题,如果一个链表有重复得元素,则没法反映出交集,所以用两个数组来存取)

	for(int i = 0; i < MAX_SIZE;i++)
	{
		if(save_array1[i] == save_array2[i] && save_array1[i] > 0)  //比较次数
			printf("%d ", i);
	}

	printf("\n");



}


void print_list(Node* head)
{
	Node* p ;
	p = head->next;

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

	printf("\n");

}


int main(int argc, char const *argv[])
{
	Node* list1 = Init_List();
	Node* list2 = Init_List();


	jiaoji(list1,list2);
	
	

	return 0;
}

在这里插入图片描述

? 2.9

//第九题在第六题的基础上边输出 边释放节点即可

//自顶向下归并排序


#include<stdio.h>
#include<stdlib.h>
#include<assert.h>


typedef struct Node
{
	int data;
	struct Node* next;

}Node;


void print_list(Node* head);

//创建一个带头节点的链表 返回链表的头指针
Node* Init_List()
{
	Node* head = (Node*)malloc(sizeof(Node));
	assert(head);

	int first,size;

	printf("please enter list sizes: ");
	scanf("%d",&size);


	head->data = 0;
	head->next = NULL;

	//采用尾插法,构建链表
	//则需要构建一个链表的尾指针
	Node* tail = head;

	for(int i = 0; i < size ; i++)
	{
		Node* new = (Node*)malloc(sizeof(Node));
		assert(new);

		scanf("%d",&first);
		new -> data = first;
		tail-> next = new;
		new -> next = NULL;
		tail = tail->next;

	}

	return head;

}



Node* merge(Node* head1 ,Node* head2)
{
	if(head1 == NULL) return head2;
	if(head2 == NULL) return head1;

	Node* res, *p;

	if(head1->data < head2->data)
	{
		res = head1;         //链接上了
		head1 = head1->next;
	}
	else
	{
		res = head2;
		head2 = head2->next;
	}

	p = res; //res作为头指针。用p来遍历建立链表

	while(head1 != NULL && head2 != NULL)
	{
		if(head1->data < head2->data)
		{
			p -> next = head1;        
			head1 = head1->next;
		}
		else
		{
			p -> next = head2;
			head2 = head2->next;
		}

		p = p->next;
	}

	if(head1 != NULL) p->next = head1;
	else if (head2 != NULL) p->next = head2;

	return res;
}

//使用自顶向下归并排序
Node* merge_sort(Node* head)
{
	if(head == NULL || head -> next == NULL) return head;
	else
	{
		//快慢指针找到中间节点.  巧妙
		Node* fast = head, *slow = head;
		while(fast->next != NULL && fast->next->next != NULL)
		{
			fast = fast->next->next;
			slow = slow->next;
		}

		fast = slow;
		slow = slow->next;
		fast->next = NULL;
		fast = merge_sort(head);//前半段排序
		slow = merge_sort(slow);

		return merge(fast,slow);
	}

	 

}

void delete_node(Node* head)
{
	Node* prev, *pcur;

	prev = pcur = head;
	pcur = pcur->next;

	while(pcur)
	{
		Node* save;
		save = pcur;
		pcur = pcur->next;
		prev -> next = pcur;

		printf("%d ", save->data);
		free(save);
	}

	printf("\n");


}

//在该算法中 这个函数没有用到
void list_length(Node* head,int* value)
{
	Node* p ;
	
	p = head->next;

	while(p != NULL)
	{
		*value = *value + 1;
		p = p->next;
	}

}

void print_list(Node* head)
{
	Node* p ;
	p = head->next;

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

	printf("\n");

}


int main(int argc, char const *argv[])
{
	Node* list = Init_List();
	
	list = merge_sort(list);

	delete_node(list);
	
	printf("origin list is: ");

	print_list(list);
	

	return 0;
}

在这里插入图片描述

? 2.10

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define MAX_SIZE 100



typedef struct Node
{
	int data;
	struct Node* next;
}Node;



//创建一个带头节点的链表 返回链表的头指针
Node* Init_List()
{
	Node* head = (Node*)malloc(sizeof(Node));
	assert(head);

	int first,size;

	printf("please enter list sizes: ");
	scanf("%d",&size);


	head->data = 0;
	head->next = NULL;

	//采用尾插法,构建链表
	//则需要构建一个链表的尾指针
	Node* tail = head;

	for(int i = 0; i < size ; i++)
	{
		Node* new = (Node*)malloc(sizeof(Node));
		assert(new);

		scanf("%d",&first);
		new -> data = first;
		tail-> next = new;
		new -> next = NULL;
		tail = tail->next;

	}

	return head;

}


Node* Init_Only()
{
	Node* head = (Node*)malloc(sizeof(Node));
	assert(head);

	head->data = 0;
	head->next = NULL;

	return head;
}

//修改指针的步长即可
void divide(Node* list1,Node* list2)
{
	Node* pcur,*prev,*q;

	pcur = list1->next->next;
	prev = list1->next;
	q = list2;

	while(pcur != NULL)
	{
		Node* save;
		save = pcur;
		prev->next = pcur->next;
		pcur = pcur->next->next;
		prev = prev->next;

		
		q->next = save;
		save->next = NULL;
		q = q->next;

	}


}


void print_list(Node* head)
{
	Node* p ;
	p = head->next;

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

	printf("\n");

}


int main(int argc, char const *argv[])
{
	Node* list1 = Init_List();
	Node* list2 = Init_Only();


	divide(list1,list2);
	
	print_list(list1);
	print_list(list2);

	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月的天气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值