?2.2
#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 x)
{
Node* p = head;
Node* q = p; //指向要删除节点的前驱
p = p->next;
while(p)
{
if(p->data == x) //下面是普通的删除操作
{
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 number you want to delete:");
int delete_number;
scanf("%d",&delete_number);
delete_value_x(list,delete_number);
print_list(list);
return 0;
}
?2.3
#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;
}
//先倒序存到一个新的链表中,然后输出
//采用头插法即可
void reverse_output(Node* head)
{
Node* reverse_first = (Node*)malloc(sizeof(Node));
assert(reverse_first);
reverse_first -> data = 0;
reverse_first -> next = NULL;
Node* p = head->next;
while(p)
{
Node* save = p;
p = p->next;
save->next = reverse_first->next;
reverse_first->next = save;
}
print_list(reverse_first);
}
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();
reverse_output(list);
return 0;
}
?2.4
#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;
}
//删除链表中的最小值
//我的方法应该不高效。我只是扫描了一遍,找到最小值,然后再删除 这样的时间复杂度只有O(n)
//如果排序再删除的话,时间复杂度只有O(nlogn)
void delete_min(Node* head)
{
Node* p = head->next;
int min = p->data;
int position = 0;
while(p)
{
if(p->data <= min) //这样的话会多扫描一些元素,不过这里忽略不记了
{
min = p->data;
position ++;
}
p = p->next;
}
Node* q = head;
for(int i = 1;i < position ;i++) //找到前驱结点
{
q = q->next;
}
//删除节点
q->next = q->next->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();
delete_min(list);
print_list(list);
return 0;
}
?2.5
链表原地循环逆值的讲解:http://www.cnblogs.com/dhls231/p/4773555.html
#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* reverse(Node* head)
{
if(head == NULL || head->next == NULL)
return head;
Node* prev = NULL;
Node* pcur = head;
while(pcur != NULL)
{
Node* ptemp = pcur;
pcur = pcur->next;
ptemp->next = prev;
prev = ptemp;
}
return prev;
}
void print_list(Node* head)
{
Node* p ;
p = head;
while(p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main(int argc, char const *argv[])
{
Node* list = Init_List();
list = reverse(list);
print_list(list);
return 0;
}