? 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;
}