生活-数据结构的第一周_(:зゝ∠)_

作业:

单链表的基操+双链表的基操


感受:

做梦梦到链表跟我说:“系兄弟就起身打我。”


问题:

  1. 搞不明白指针的指针,申请内存时候花了很多时间。->加上*当初一级指针使用。
  2. 多文件路径问题,头文件main中引用就可以了。
  3. 不会丢弃数据,一下子输入很多数据就疯狂输出。
  4. 项目结构要优化。

收获:

  1. 认识了双向链表。
  2. 双向链表的销毁要把前指针也指向NULL,不然会因为指向已释放内存报错。
  3. 遍历不能动头指针。
  4. 做完自定义插入感觉自己牛逼坏了。

代码:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "linkedList.h"

Status InitList(LinkedList *L) {
    //初始化链表
    *L=(LinkedList)malloc(sizeof(LNode));
    if(*L==NULL)return 0;
    else {
        (*L)->next=NULL;
        printf("请输入一个整型数据:\n");
        while(!(scanf("%d",&((*L)->data)))){
            printf("请输入正确的数据类型!\n");
            setbuf(stdin, NULL);
        }
        return 1;
    }
}


void DestroyList(LinkedList *L){    //销毁链表
    LinkedList p = *L;
    while((*L)->next){
        p=(*L)->next;
        free(*L);
        *L=p;
    }
    free(*L);
    *L = NULL;
    printf("销毁完成\n");
}


Status InsertList(LNode *p, LNode *q) {
    //在节点p之后插入节点q
    LNode *r;
    if(p==NULL){
        return 0;
    }else{
        if(p->next==NULL){
            p->next=q;
            q->next=NULL;
        }else{
            r=p->next;
            p->next=q;
            q->next=r;
        }
        return 1;
    }
}

Status DeleteList(LNode *p, ElemType *e) {
    //删除节点p后的第一个节点,并将其值赋给e
    if(p==NULL||p->next==NULL)return 0;
    else{
        if(p->next->next==NULL){
            e=&(p->next)->data;
            p->next=NULL;
        }else{
            e=&(p->next)->data;
            p->next=p->next->next;
        }
        return 1;
    }
}

void TraverseList(LinkedList L, void (*visit)(ElemType e)) {
    //遍历
    LinkedList p;
    for(p=L;p->next!=NULL;p=p->next)printf("%d ",p->data);
    printf("%d\n",p->data);
}


Status SearchList(LinkedList L, ElemType e) {
    //根据e找到链表中的第一个节点
    LinkedList p;
    ElemType i=0,f=0;
    if(L->data==e){
        i=1;
        f=1;
        return i;
    }
    else{
        for(p=L;p!=NULL;i++){
            if(p->data==e){
                f=1;
                break;
            }
            if(p->next==NULL)break;
            p=p->next;
        }
        if(f)return i+1;
        else return 0;
    }
}


Status ReverseList(LinkedList *L) {
    //反转
    LinkedList p=NULL,q=NULL,r=NULL;
    int i=1;
    if((*L)->next==NULL)i=0;
    else if((*L)->next->next==NULL){
        p=(*L)->next;
        (*L)->next=NULL;
        p->next=(*L);
        *L=p;
        for(;(*L)->next!=NULL;*L=(*L)->next){
            printf("%d ",(*L)->data);
        }
        printf("%d\n",(*L)->data);
        *L=p;
    }else{
        p=*L;
        q=(*L)->next;
        r=(*L)->next->next;
        p->next=NULL;
        while(1){
            q->next=p;
            p=q;
            q=r;
            if(q->next==NULL){
                r->next=p;
                break;
            }
            r=r->next;
        }
        for(*L=r;r->next!=NULL;r=r->next)printf("%d ",r->data);
        printf("%d\n",r->data);
    }
    return i;
    
}


Status IsLoopList(LinkedList L) {
    //判断是否循环
    LinkedList q=NULL,p=NULL;
    int i=0;
    q=p=L;
    while(q->next!=NULL&&q->next->next!=NULL){
        p=p->next;
        q=q->next->next;
        if(p==q){
            i=1;
            break;
        }
    }
    return i;
    
}


LNode* FindMidNode(LinkedList *L) {
     LinkedList p=NULL,q=NULL;
     p=q=*L;
     if(p->next==NULL||p->next->next==NULL){
         printf("%d \n",p->data);
         return p;
     }else{
         while(q->next!=NULL&&q->next->next!=NULL){
             p=p->next;
             q=q->next->next;
         }
         printf("%d \n",p->data);
         return p;
     }
 }

Status add(LinkedList *L){
    LinkedList q=NULL,p=NULL;
    ElemType a = 0;
    while(!(scanf("%d",&a))){
        printf("请输入正确的数据类型!\n");
        setbuf(stdin, NULL);
    }
    if((*L)->next==NULL){
        p=(LinkedList)malloc(sizeof(LNode));
        (*L)->next=p;
        p->data=a;
    }else{
        for(q=*L;q->next!=NULL;q=q->next)continue;
        p=(LinkedList)malloc(sizeof(LNode));
        q->next=p;
        p->data=a;
    }
    p->next=NULL;
    return 1;
}


int main(int argc, const char * argv[])
{
    LinkedList L=NULL,L0=NULL,newNode=NULL,insert=NULL,del=NULL;
    ElemType delete=0;
    ElemType c=0,search=0,searched=0;
    void (*visit)(ElemType e) = NULL;
    int cho=0,f=0;
    do{
        printf("*****************请选择********************\n");
        printf("**************1.构造链表*******************\n");
        printf("**************2.结束程序*******************\n");
        setbuf(stdin, NULL);
        scanf("%d",&cho);
        switch(cho){
            case 1:
                if(InitList(&L)){
                    printf("构造完成\n");
                    f=0;
                }
                else {
                    printf("构造失败\n");
                    f=1;
                }
                break;
            case 2:exit(1);break;
            default:
                printf("请输入正确的指令!\n");
                f=1;
        }
    }while(f);
    do{
        printf("*****************请选择********************\n");
        printf("**************1.销毁链表*******************\n");
        printf("**************2.插入节点*******************\n");
        printf("**************3.删除节点*******************\n");
        printf("**************4.遍历链表*******************\n");
        printf("**************5.寻找节点*******************\n");
        printf("**************6.反转链表*******************\n");
        printf("**************7.判断循环*******************\n");
        printf("**************8.寻找中点*******************\n");
        printf("**************9.输入数据*******************\n");
        printf("**************0.结束程序*******************\n");
        setbuf(stdin, NULL);
        scanf("%d",&cho);
        switch(cho){
            case 1:DestroyList(&L);break;
            case 2:
                printf("请输入想要查找的节点数据:\n");
                scanf("%d",&search);
                searched=SearchList(L, search);
                while(!searched){
                    printf("未找到该节点,请重新输入:\n");
                    setbuf(stdin, NULL);
                    scanf("%d",&search);
                    searched=SearchList(L, search);
                }
                setbuf(stdin, NULL);
                printf("已找到该节点,请输入想插入的数据:\n");
                newNode=(LinkedList)malloc(sizeof(LNode));
                if(newNode==NULL){
                    printf("申请内存失败\n");
                    exit(-1);
                }
                while(!(scanf("%d",&(newNode->data)))){
                    printf("请输入正确的数据类型!\n");
                    setbuf(stdin, NULL);
                }
                insert=L;
                for(ElemType i=1;i<searched;i++){
                    insert=insert->next;
                }
                if(InsertList(insert,newNode))printf("插入成功\n");
                else printf("插入失败\n");
                break;
            case 3:
                printf("请输入想要查找的节点数据:\n");
                scanf("%d",&delete);
                searched=SearchList(L, delete);
                while(!searched){
                    printf("未找到该节点,请重新输入:\n");
                    setbuf(stdin, NULL);
                    scanf("%d",&delete);
                    searched=SearchList(L,delete);
                }
                setbuf(stdin, NULL);
                printf("已找到该节点 位于第%d位\n",searched);
                del=L;
                for(ElemType i=1;i<searched;i++){
                    del=del->next;
                }
                if(DeleteList(del,&delete)) printf("删除成功\n");
                else printf("该节点不可删除\n");
                break;
            case 4:TraverseList(L,(*visit));break;
            case 5:
                printf("请输入要查询的数据:\n");
                scanf("%d",&c);
                if(SearchList(L,c))printf("已找到 在第%d个节点\n",SearchList(L,c));
                else printf("未找到\n");
                break;
            case 6:
                if(ReverseList(&L))printf("反转完成\n");
                else printf("该链表不可反转\n");
                break;
            case 7:
                if(IsLoopList(L))printf("存在成环\n");
                else printf("没有成环\n");
                break;
            case 8:L0=FindMidNode(&L);break;
            case 9:
                printf("请输入一个整型数据:\n");
                if(add(&L))printf("添加成功!\n");
                break;
            case 0:exit(1);
            default:printf("请输入正确的指令!\n");
        }
    }while(L!=NULL);
    return 0;
}

下一周也要加油鸭
2019.3.25

猜你喜欢

转载自blog.csdn.net/weixin_43606809/article/details/88808162