zoukankan      html  css  js  c++  java
  • 数据结构(2)链表的实现

    这个实现可能有许多的错误, 还有最后最数据结构最后的测试上, 费了不少力, 请大家看完后不吝赐教!!!

    贴代码啦

    LinkList.h

    #ifndef _SINGLELINKLIST_H
    #define _SINGLELINKLIST_H
    
    /*这是一种简单的链表的实现方式*/
    //typedef int Elemtype;
    
    struct node;
    /*刚开始这个地方写成了typedef struct *PtrToNode;最后导致无法编译*/
    typedef struct node *PtrToNode;
    
    
    /*在结构体后面没有定义指针,而是使用了如下的定义 ,在编译时出现left of 'next' specifies undefined struct/union '$S1'*/
    typedef PtrToNode List;
    typedef PtrToNode Position;
    
    
    typedef struct{
        char key[15];
        char name[20];
        int age;
    }Elemtype;
    
    typedef struct node
    {
        Elemtype elem;
        struct node * next;
    };//*Position,*List;
    
    /* 初始化头结点*/
    /* 第一种初始化方式*/
    //List InitList(List L);
    /* 第二种初始化方式*/
    void InitList(List *L);
    
    /* 是不是空表*/
    int IsEmpty(List L);
     
    /* 判断是不是最后一个元素*/
    int IsLast(List L, Position P);
    
    /* 插入元素,倒插法,新插入的元素为表的第一个元素*/
    void AddFirst(List L, Elemtype elem);
    
    /* 插入元素,插入元素到表尾*/
    void AddEnd(List L, Elemtype elem);
    
    /* 返回特定的数据在表中位置*/
    Position Find(List L, char *key);
    
    /* 如果key找到, 则返回key对应的前一个节点*/
    Position FindPrevious(List L, char *key);
    
    
    /* 在特定结点的后面插入新的结点*/
    int Insert(List L, Elemtype elem, char *key);
    
    /* 删除表中某个特定元素*/
    int Delete(List L, char *key);
    
    /* 销毁表*/
    void DeleteList(List L);
    
    /*获取链表的长度*/
    int Length(List L);
    
    /*遍历*/
    void traverse(List L);
    
    #endif    /*_SINGLELINKLIST_H*/

    LinkList.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "LinkList.h"
    
    // /* 1. 第一种初始化写法::不要这么写;*/
    // /* 2. 因为表头是亚节点,所以初始化需要分配空间*/
    // /* 3. 函数的返回值必须是堆变量如果是栈变量,那么在函数返回的时候就会被销毁*/
    // List InitList(List L)
    // {
    //     L=(struct node *)malloc(sizeof(struct node));
    //     L->next=NULL;
    //     return L;
    //     /*哑节点如果这样初始化就会出现NullPointException,当然这样的错误vc不会提示*/
    //     //L = NULL;
    // }
    
    /* 0. 第二种写法*/
    /* 1. 刚开始由于不懂运算优先级将*L->next=NULL,->的优先级高于*,并且最后导致编译失败*/
    void InitList(List *L)
    {
        *L=(List)malloc(sizeof(struct node));
        (*L)->next=NULL;
    }
    
    /* 空表返回T, 反之放回F*/
    int IsEmpty(List L)
    {
        return L->next == NULL;
    }
    
    /* 判断是不是最后一个元素*/
    int IsLast(List L, Position P)
    {
        return P->next == NULL;
    }
     
    /* 插入元素,倒插法,新插入的元素为表的第一个元素*/
    void AddFirst(List L, Elemtype elem)
    {
        Position tmpcell;
    
        if (!(tmpcell = (struct node *)malloc(sizeof(struct node))))
        {
            printf("节点内存分配失败啦
    ");
            return ;
        }
        tmpcell->elem = elem;
        tmpcell->next = L->next;
        L->next = tmpcell;
    }
    
    /* 插入元素,插入元素到表尾*/
    void AddEnd(List L, Elemtype elem)
    {
        Position tmpcell,h;
    
        /* 分配一个节点内存*/
        if (!(tmpcell = (struct node *)malloc(sizeof(struct node))))
        {
            printf("节点内存分配失败啦
    ");
            return ;
        }
        tmpcell->elem = elem;
        tmpcell->next = NULL;
        
        /* 如果是空表*/
        if (L->next == NULL)
        {
            L->next = tmpcell;
            return;
        }
    
        /* 如果不是空表*/
        /* 移动节点指针,让它指向最后一个节点位置*/
        h = L->next;
        while (h != NULL && h->next != NULL)
            h = h->next;
    
        /* 自己犯得错误写法, 注解一下嘿嘿,导致了h是控制空指针*/
        /* 刚开始h到这个地方的时候是空指针,所以下面的写法是错误滴,现在修改好了呀*/
        h->next = tmpcell;
    }
    
    
    /* 返回特定的数据在表中位置*/
    /* 1. 如果遍历完后,没有发现这个指针,返回的应该是链表的最后一个元素,应该是NULL*/
    /* 2. 这个算法实现参考自 数据结构与算法分析:c语言描述*/
    Position Find(List L, char *key)
    {
        Position p;
    
        p = L->next;
        while (p != NULL && !(strcmp(p->elem.key,key) == 0))
            p = p->next;
    
        return p;
    }
    
    /* 如果key找到, 则返回key对应的前一个节点*/
    Position FindPrevious(List L, char *key)
    {
        Position p;
        p = L;
    
        if (L->next->next == NULL)
            return NULL;
    
        while (p->next != NULL && !(strcmp(p->next->elem.key,key) == 0))
            p = p->next;
        return p;
    }
    
    /*在特定结点的后面插入新的结点*/
    int Insert(List L, Elemtype elem, char *key)
    {
        Position p, tmpcell;
    
        if (!(tmpcell = (struct node *)malloc(sizeof(struct node))))
        {
            printf("节点内存分配失败啦
    ");
            return 0;
        }
        
        p = Find(L,key);
        if (p)
        {
            tmpcell->elem = elem;
            tmpcell->next = p->next;
            p->next = tmpcell;
        }
        else
        {
            free(tmpcell);
            printf("插入节点失败
    ");
        }
        return 1;
    }
    
    /*删除表中某个特定元素*/
    int Delete(List L, char *key)
    {
        Position p,tmpcell;
    
        p = Find(L,key);
    
        if (!IsLast(L,p))
        {
            tmpcell = p->next;  
            p->next = p->next->next;
            free(tmpcell);
        }
        return 1;
    }
     
    /* 销毁表*/
    void DeleteList(List L)
    {
        Position p,tmpcell;
    
        p = L->next;
        L->next = NULL;
    
        while (p->next != NULL)
        {
            tmpcell = p->next;
            free(p);
            p = tmpcell;
        }
    }
    
    /*获取链表的长度*/
    int Length(List L)
    {
        int i = 0;
        Position p;
        
        p = L->next;
    
        while (p != NULL)
        {
            i++;
            p = p->next;
        }
        return i;
    }
    
    /* 遍历*/
    void traverse(List L)
    {    
        Position p;
        p = L->next;
    
        if (L->next== NULL)
            return;
    
        printf("
    当前单链表中所有的存储的数据为:
    ");
    
        while(p!= NULL)
        {
            /*在这个地方第一次写成了L,并导致失败!*/
            printf("%s  %s  %d  
    ",p->elem.key,p->elem.name,p->elem.age);
            p = p->next;
        }
    }

    最后测试,也是最破烦的, 由于半路出家,  不太会, 由着自己写啦

    #include <stdio.h>
    #include <string.h>
    
    #include "LinkList.h"
    
    
    int main()
    {
        
        Elemtype elem;
        List L;
        Position p;
        char buf[15]; //key
    
        int len;
    
        /*1. 第一种初始化*/
        /*2. 不过这种不建议实用*/
        //L = InitList(L);
    
        /*拾遗. 1. 如果指针没有初始化,那么L==0xcccccccc*/
        /*拾遗. 2. 想要修改或者是保存某个实参变量的值,那么就应该传递指向这个实参变量的指针*/
        /*2. 第二种初始化方式*/
        InitList(&L);    
    
        printf("请输入 关键词 姓名 年龄(关键词输入0 ,则退出)
    ");
        
        /*插入一些数据到表中*/
        do 
        {
            printf("请输入关键词
    ");
            fflush(stdin);
            scanf("%s",elem.key);
            if (strcmp(elem.key,"0")==0)    
                break;
            scanf("%s%d",elem.name,&elem.age);
            //AddFirst(L,elem);//测试通过
            AddEnd(L,elem);
        } while (1);
        
    
    //     /* 测试在表头进行插入*/
    //     fflush(stdin);
    //     scanf("%s",elem.key);
    //     scanf("%s%d",elem.name,&elem.age);
    //     AddFirst(L,elem);
    
    //     /* 测试查找给定关键词所对应的节点*/
    //     p = Find(L, "chen");
    //     if (p)
    //         printf("
    %s  %s  %d",p->elem.key, p->elem.name, p->elem.age);
    
    //     /* 测试查找给定关键词所对应的前一个节点*/
    //     p = FindPrevious(L, "chen");
    //     if (p)
    //         printf("
    %s  %s  %d",p->elem.key, p->elem.name, p->elem.age);
    
    //     /* 测试插入元素*/
    //     printf("
    请输入插入的关键词位置啦");
    //     fflush(stdin);    
    //     scanf("%s",buf);
    //     printf("
    请输入插入的元素!!!
    ");
    //     fflush(stdin);
    //     scanf("%s",elem.key);
    //     scanf("%s%d",elem.name,&elem.age);
    //     Insert(L,elem, buf);
    
    
    //     /* 测试表是否为空*/
    //     if (IsEmpty(L))
    //         printf(">>>>>>>>>>>>>>>>>>>>>>是空表!
    ");
    //     else
    //         printf(">>>>>>>>>>>>>>>>>>>>>>表中含有数据!
    ");
         
    
    //     /* 测试删除指定位置的元素*/
    //     printf("
    请输入删除的关键词位置啦
    ");
    //     fflush(stdin);
    //     scanf("%s",buf);
    //     Delete(L,buf);
    
    //     /* 测试取得链表的长度*/
    //     len = Length(L);
    //     printf("
    %d",len);
    
    //     traverse(L);    
    //     DeleteList(L);    
    
        traverse(L);
        free(L);
        return 0;
    }
  • 相关阅读:
    Nginx的配置文件详解(超详细)
    淘宝地址爬取及UI展示
    点击观看
    winform picturebox设置布局样式
    vs的一个不经常用的快捷键
    C# 开发windows服务
    winform窗体置顶
    C# mysql set和enum属性字段的读取和添加
    winform窗体绑定监控键盘事件
    html5创建的sqlite存放为止以及在手机中的位置
  • 原文地址:https://www.cnblogs.com/dLong/p/3371344.html
Copyright © 2011-2022 走看看