基本数据结构 -- 链表的创建、遍历、查找、插入和删除及释放内存

#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;

}

结果:

10bb35a31de7902fadab928322de286f1db.jpg

转载于:https://my.oschina.net/1024and1314/blog/3096919

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值