#include<stdio.h>
#include<stdlib.h>
typedef struct Link{
int data;
struct Link* next;
}Linknode;
int number=0;
//单链表的操作,头指针不能动(一定要记住)
//节点的添加,在结尾,并返回头节点
Linknode* AddNode(Linknode *head){
Linknode* p= NULL;
Linknode* pre=head;
int data = 0;
p = (Linknode*)malloc(sizeof(Linknode));
//分配内存是否成功
if(!p){
printf("No enough memory to allocate!");
exit(0);
}
//判断头节点是否为NULL
if(head == NULL){
head = p;
}else{
//便利到链表的尾部
while(pre->next != NULL){
pre = pre->next;
}
//将p接到pre后
pre->next = p;
}
printf("please input addnode data: ");
scanf("%d",&data);
//将会车键读出
getchar();
p ->data = data;
p->next = NULL;
number++;
return head;
}
//节点的删除,并返回头节点
//情况:1.删除头节点 2,删除中间节点 3.删除尾部节点 4:空表,不需要操作
Linknode* Delete(Linknode* head,int deleteData){
Linknode* pre = head; //当前节点
Linknode* p = head; //当前节点的下一个节点,也是要删除节点可能位置
//判断是否为NULL
if(head == NULL){ //4:空表,不需要操作的情况
printf("the linkList is empty! \n");
return head;
}
while(p->data != deleteData && p->next!= NULL){ //未找到删除节点且到达链表尾部,这样pre只用到达最后一个节点的上一个节点的位置
pre = p; //pre当前节点
p = p->next; //下一个节点
}
if(p->data == deleteData){ //找到删除节点
if(p == head){ //1.删除头节点的情况
head = p->next;
number--;
}else{ //2,删除中间节点 3.删除尾部节点 的情况都包括了
pre->next = p ->next;
number--;
}
free(p);
}else{ //到达位置仍没有找到要删除的节点
printf("no the deleteData:%d\n",deleteData);
}
return head;
}
//节点的插入,假设已经排好序
//前提已经排好序的链表
//情况如下:1.为空表 2.插入到头节点 3:中间部分 4:链表的尾部
Linknode* InsertNode(Linknode* head, int nodeData){
Linknode* pre = head;
Linknode* p = head;
//先生成该节点
Linknode* temp = (Linknode*)malloc(sizeof(Linknode));
//是否分配内存成功,必须判断
if(!temp){
printf("No enough memory to allocate!");
exit(0);
}
temp ->next = NULL;
temp ->data= nodeData;
if(head == NULL){ //1.为空表的情况
//则将p 作为头节点
head = temp;
number++;
return head;
}
while(p->data <= nodeData && p->next !=NULL)
{
pre =p;
p= p->next;
}
if(p ->data > nodeData){
if(p == head){
head = temp;
number++;
}else {
pre ->next = temp;
temp->next = p;
number++;
}
}else{
p->next = temp;
number++;
}
return head;
}
//链表的打印
void printLink(Linknode* head){
Linknode *pre = head;
if(head ==NULL){
printf("NULL");
}
while(pre!= NULL){
printf("%d ", pre->data);
pre = pre ->next;
}
printf("\n");
}
//链表的释放,不破坏头指针
void freeLink(Linknode * head){
Linknode *pre = head;
Linknode *p = head;
while(p!=NULL){
pre = p;
p = p ->next;
free(pre);
}
}
//链表的排序,归并排序
Linknode * merge(Linknode *left, Linknode *right){
if(left == NULL) return right;
else if(right == NULL) return left;
if(left->data <= right->data){
left->next = merge(left->next, right);
return left;
}else{
right->next = merge(right->next,left);
return right;
}
}
Linknode * merge_Sort(Linknode* head, int number){
Linknode* left = NULL, *right= NULL;
int mid = 0;
if(head==NULL || head ->next ==NULL){
return head;
}else{
mid = (number+1)/2;
left= merge_Sort(head,mid);
right = merge_Sort(head+mid,number-mid);
return merge(left,right);
}
}
int main(){
Linknode* head= NULL;
char ch;
int data= 0;
printf("第一步先添加入节点,然后才能删除节点,和排序节点: a:添加节点 d:删除节点 i:插入节点\n");
while(1){
printf("请输入你的操作: ");
scanf("%c",&ch);
getchar();
switch (ch)
{
case 'a':
head = AddNode(head);
printf("节点数量:%d\n",number);
printLink(head);
break;
case 'd':
printf("please input deleteData:");
scanf("%d",&data);
getchar();
head = Delete(head,data);
printLink(head);
printf("节点数量:%d\n",number);
break;
case 'i':
head = merge_Sort(head,number);
printf("please input insertdata:");
scanf("%d",&data);
getchar();
head = InsertNode(head,data);
printf("节点数量:%d\n",number);
printLink(head);
break;
default:
break;
}
}
freeLink(head);
return 0;
}
结果: