zoukankan      html  css  js  c++  java
  • 数据结构(1)顺序表的实现

    Sqlist.h

    #ifndef _SQLIST_H_
    #define _SQLIST_H_
    
    #define LIST_INIT_SIZE 1
    #define LISTINCREAMENT 1
    
    //#define ElemType int
    
    typedef struct
    {
        char name[20];
        int age;
    }ElemType;
    
    /************************************************************************/   
    /* 存储结构的定义                                                       */   
    /************************************************************************/
    typedef struct  
    {
        ElemType *elem; /*基址的指针*/
        int length;    /*表的长度,表中元素的个数*/
        int size;    /*表的容量*/
    }Sqlist;
    
    /************************************************************************/
    /* 表的基本操作                                                         */
    /************************************************************************/
    void InitList(Sqlist *L);/*初始化表*/
    void DestroyList(Sqlist *L);/*销毁表,释放存储空间*/
    void ClearList(Sqlist *L);/*将表置空*/
    
    int IsEmpty(Sqlist *L);/*判断表是否为空,空则返回1,否则返回0 */
    int Length(Sqlist *L);/*返回表的长度*/
    
    ElemType *GetElem(Sqlist *L, int i);  /*返回表中第i个元素*/
    int LocateElem(Sqlist *L, ElemType e);/*判断e是否为表中的元素,是则返回元素在表中的位置,否则返回-1*/
    
    /*用pre_e获取元素e的前驱,返回值i为前驱在表中位置*/
    /*如果e不在表中,返回-1 */
    /*如果e为表中的第一个元素,返回-2*/
    int PriorElem(Sqlist *L, ElemType e, ElemType *pre_e);
    /*用next_e获取e的后继,返回值i为后继在表中的位置*/
    /*如果e不是表中元素,返回-1*/
    /*如果e为表中的最后一个元素,返回-2*/
    int NextElem(Sqlist *L, ElemType e, ElemType *next_e);
    
    /*在位置i处插入元素e,成功则返回表的长度,否则返回0*/
    int Insert(Sqlist *L, ElemType e, int i);
    /*删除表中的元素e,成功返回1,否则返回0*/
    int Delete(Sqlist *L, int n,  ElemType *e);
    /*遍历*/
    void traverse(Sqlist *L);
    
    #endif

    Sqlist.c

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #include "Sqlist.h"
    
    /*初始化表*/
    void InitList(Sqlist *L)
    {
        L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
        if (!L->elem)
        {
            printf("动态内存分配失败
    ");
            exit(0);
        }
    
        L->length = 0;
        L->size = LIST_INIT_SIZE;
    }
    
    /*销毁表,释放存储空间*/
    void DestroyList(Sqlist *L)
    {
        if (L->elem)
            free(L->elem);
    }
    
    /*将表置空*/
    void ClearList(Sqlist *L)
    {
        if (L->elem)
            L->length = 0;
    }
    
    /*判断表是否为空,空则返回1,否则返回0 */
    int IsEmpty(Sqlist *L)
    {
        if (L->elem)
        {
            if (L->length > 0)
                return 0;
            else
                return 1;
        }else
            return -1;
    }
    /*返回表的长度*/
    int Length(Sqlist *L)
    {
        if (L->elem)
            return L->length;
        else 
            return -1;
    }
    
    /*返回表中第i个元素*/
    ElemType * GetElem(Sqlist *L, int i)
    {
        if (i<1 || i> L->length)
        {
            printf("此节点不存在,请检查是否正确!!!
    ");
            return NULL;
        }
    
        return &(L->elem[i-1]);
    }
    
    /*判断e是否为表中的元素,是则返回元素在表中的位置,否则返回-1*/
    int LocateElem(Sqlist *L, ElemType e)
    {
        int i;
        for (i = 0; i < L->length; i++)        
        {
            //如果使用e.name == L->elem[i].name 经过测试失败(e.name="chen",同样L->elem[i].name= "chen")
            //从首地址开始逐个遍历字符比较是可以的,也就是strcmp,string.h
            if (strcmp(L->elem[i].name,e.name) == 0)  
                return i+1;
        }
        return -1;
    }
    
    /*用pre_e获取元素e的前驱,返回值i为前驱在表中位置*/
    /*如果e不在表中,返回-1 */
    /*如果e为表中的第一个元素,返回-2*/
    int PriorElem(Sqlist *L, ElemType e, ElemType *pre_e)
    {
        int local;
        local = LocateElem(L, e);
        if (local == -1)//表中不存在该元素
            return -1;
        if (local == 1)//表中的第一个元素
            return -2;
    
        pre_e = &(L->elem[local-1]);
        //*pre_e = L->elem[local-1] //会出错
        return (local-1);
    }
    
    int NextElem(Sqlist *L, ElemType e, ElemType *next_e)
    {
        int local;
        local = LocateElem(L, e);
        if (local == -1)//表中不存在该元素
            return -1;
        
        *next_e = L->elem[local+1];
        return (local+1);
    }
    
    /*
    在位置i处插入元素e,成功则返回表的长度,否则返回0
    */
    int Insert(Sqlist *L, ElemType e, int i)
    {
        ElemType * temp;
        int cursor;
    
        if (i < 1 || i > L->length + 1)
        {
            printf("
    插入位置出错啦(温馨提示n个元素,有n+1个插入位置)
    ");
            return 0;
        }
        
        /*应该在此添加插入位置是否合法的判断条件*/
        if (L->length >= L->size)
        {
            /*这个很耗内存,不建议使用realloc*/
            temp = (ElemType *)realloc(L->elem, (L->size + LISTINCREAMENT)*sizeof(ElemType));
            if (!temp)
            {
                printf("动态内存分配失败overflow!!!
    ");
                return 0;
            }
            L->elem = temp;
            L->size += LISTINCREAMENT;
        }
    
        /*
        debug error:Damage before normal block
        编译器报这样的错,几乎可以肯定是在程序中,数组访问越界,
        这面这个肯定最后一个元素是空数据,或者是垃圾数据
        DAMAGE:After normal block(#****)  
        */
        for (cursor = L->length-1; cursor >= i-1; cursor --)
            L->elem[cursor + 1] = L->elem [cursor];
        
        L->elem[i-1] = e;
        L->length++;
    
        return 1;
    }
    
    /*
    在位置n处插入元素,并将删除元素保存在e当中
    */
    int Delete(Sqlist *L, int n, ElemType *e)
    {
        int i;
    
        if (n < 1 || n > L->length)
        {
            printf("删除位置不合法!!!
    ");
            return -1;
        }
        
        e = &(L->elem[n-1]);
    
        for (i = n-1; i < L->length; i++)
            L->elem[i] = L->elem[i + 1];
    
        L->length --;
        return 1;
    }
    
    void traverse(Sqlist *L)
    {
        int i = 0;
        if (!L->elem || L->length ==0)
            return;
        for (; i< L->length; i ++)
        {
            printf("
    顺序表中第%d个元素分别为:(%s,%d)", i, L->elem[i].name,L->elem[i].age);
        }
        printf("
      ");
    }

    main.c

    #include "Sqlist.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    
    int main()
    {
        Sqlist L;
        int i;
    
        ElemType e, *ptr_e;
    
        InitList(&L);
        
        /*测试插入元素,在头元素位置和尾元素单独测试*/
        printf("请输入要添加的节点元素:
    例如:chen 23
    ");
        for (i = 1; i < 4; i++)
        {
            fflush(stdin);
            scanf("%s%d",&e.name,&e.age);
            Insert(&L,e,i);
        }
        
    /*
        //测试第一个位置
        printf("
    测试第一个位置插入
    ");
        fflush(stdin);
        scanf("%s%d",&e.name,&e.age);
        Insert(&L,e,1);
        traverse(&L);
        printf("%d",L.size);
        printf("  %d
    ",L.length);
        
            
        //测试最后一个位置
        printf("
    测试最后一个位置插入
    ");
        fflush(stdin);
        scanf("%s%d",&e.name,&e.age);
        Insert(&L,e,L.length+1);    
        traverse(&L);
        printf("%d",L.size);
        printf("  %d
    ",L.length);
    */
        
        
    /*
        //测试删除第一个元素
        Delete(&L,1, &e);
        traverse(&L);
        printf("%d",L.size);
        printf("  %d
    ",L.length);
        printf("
    您所删除的元素是:(%s,%d)",e.name,e.age);
    
        //测试删除最后一个个元素
        Delete(&L,L.length, &e);
        traverse(&L);
        printf("%d",L.size);
        printf("  %d
    ",L.length);
        printf("
    您所删除的元素是:(%s,%d)",e.name,e.age);
    
        printf("
    ");
    */
    
    /*
        //测试取出指定位置上的元素;
        for (i = 1; i < 4; i ++)
        {
            e = *GetElem(&L,i);
            printf("
    您所找的元素是:(%s,%d)",e.name,e.age);
        }
    */
    /*
        //测试定位元素
        printf("请输入要定位的元素:例如(name age)
    ");
        scanf("%s%d",&e.name, &e.age); //如果这个地方丢了&,就会出现unhandle exception
        i = LocateElem(&L, e);
        printf("
    元素的位置是:%d", i);
        
    */
    
        //测试查找前一个元素
        printf("请输入要定位的元素:例如(name age)
    ");
        scanf("%s%d",&e.name, &e.age);
        i = PriorElem(&L, e, ptr_e);
        printf("
    元素的位置是:%d", i);
        
    
        
        DestroyList(&L);    
        printf("
    ");
        return 0;
    }

     

  • 相关阅读:
    Fragment_3_Androidx中返回键的处理
    2.2.3.Architecture components_View Binding
    2.2.2.Architecture components_data binding2_源码分析
    经典排序
    动态规划求解最长公共子序列
    全排列问题
    钢条切割
    KMP
    Queue
    Stack
  • 原文地址:https://www.cnblogs.com/dLong/p/3336651.html
Copyright © 2011-2022 走看看