动态顺序表的基本实现

#include<stdio.h>
#include<stdlib.h>
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define Status int
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define ElemType int

typedef struct
{
    ElemType * elem;
    int length;          //有效元素的个数 
    int listsize;         //容量 
}SqList;

//比较函数
int equals(int a, int b)
{
    if(a == b)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int cmpmax(int a, int b)
{
    if(a > b)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int cmpmin(int a, int b)
{
    if(a < b)
    {
        return 1;
    }
    else
    {
        return 0;
    }
} 

//初始化
Status InitList(SqList *L)
{
    L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
    if(!L->elem)
    {
        exit(OVERFLOW);
    }
    
    L->length = 0;
    L->listsize = LIST_INIT_SIZE;
    
    return OK;
}

//查找符合条件的元素的位置 
int LocateElem(SqList* L, int e, int(*pf)(int, int))      //获取第一个e元素的位置
{
    int i = 0;
    while (i < L->length)
    {
        if ((*pf)(L->elem[i], e))
        {
            return i+1;
        }
        else
        {
            i++;
        }    
    }
    return 0; 
}

//得到指定位置元素的值  
int GetElem(SqList* L, int i, int* e)  //取第i个数据元素 
{
    if (i < 1 || i > L->length || L->length == 0)       //操作失败 
    {
        return ERROR;
    }
    else
    {
        *e = L->elem[i-1];
        return OK;
    }
}

//插入
Status ListInsert(SqList *L, int i,ElemType e)
{
    ElemType * newbase = NULL;
    int j;
    
    if(i < 1 || i > L->length + 1)
    {
        printf("插入位置不合法!\n");
        return ERROR;
    }
    if(L->length >= L->listsize)
    {
        //使用newbase接受的好处:因为realloc重新分配一块空间,很可能会换一个位置分配,然后再将
        //原来的值复制过去,如果realloc分配失败,返回NULL,那么原顺序表的信息全部丢失 
        newbase = (ElemType *)realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(ElemType));
        if(!newbase)
        {
            exit(OVERFLOW);         //内存分配失败 
        }
        L->elem = newbase;
        L->listsize = L->listsize + LISTINCREMENT; 
    }
    
    for(j = L->length-1; j >= i-1; ++j)
    {
        L->elem[j+1] = L->elem[j];
    }
    
    L->elem[i-1] = e;
    L->length++;
    return OK;
}

//删除
Status ListDelete(SqList *L,int i,ElemType *e)
{
    if(i < 1 || i > L->length)
    {
        printf("操作失败,删除位置错误!\n");
        return ERROR;
    }
    
    (*e) = L->elem[i-1];
    
    for(; i < L->length; ++i)
    {
        L->elem[i-1] = L->elem[i];
    }
    
    L->length--;
    return OK;
}

//输出打印
void ListPrint(SqList L)
{
    int i;
    if(!L.elem)
    {
        printf("顺序表已销毁!\n");
    }
    else if(!L.length)
    {
        printf("顺序表为空!\n");
    } 
    else
    {
        for(i = 0; i < L.length; ++i)
        {
            printf("%d ", L.elem[i]);
        }
    }
    
    printf("\n");
}

//删除最小
void DeleteMin(SqList *L)
{
    int min, tag, i, e;
    if(0 == L->length)
    {
        printf("线性表已空,操作失败!");
    }
    min = L->elem[0];
    tag = 0;
    
    for(i = 1; i < L->length; ++i)
    {
        if(L->elem[i] < min)
        {
            min = L->elem[i];
            tag = i;
        }
    }
    ListDelete(L, tag + 1, &e);
}

void Destroy_List(SqList *L)
{
    if(NULL != L->elem)         //如果free(NULL),程序会崩溃 
    {
        free(L->elem);
        L->elem = NULL;
    }
    L->length = 0;
}

void Clear_List(SqList *L)
{
    L->length = 0;
}

int main(void)
{
    SqList L;
    int i;
    ElemType e;
    ElemType data[9] = {11,-22,-33,3,-88,21,77,0,-9}; 
    InitList(&L);
    for (i = 1; i <= 9; i++)
    {
        ListInsert(&L,i,data[i-1]);
    }
    printf("插入完成后 L = : ");
    ListPrint(L);
    ListDelete(&L, 2, &e);
    printf("删除第 2 个后L = : ");
    ListPrint(L);
    DeleteMin(&L);
    printf("删除L中最小值后L = : ");
    ListPrint(L);
    DeleteMin(&L);
    printf("删除L中最小值后L = : ");
    ListPrint(L);
    DeleteMin(&L);
    printf("删除L中最小值后L = : ");
    ListPrint(L);
    Destroy_List(&L);
    ListPrint(L); 
    return 0;
}
posted @ 2019-07-13 20:08  telankesi  阅读(228)  评论(0编辑  收藏  举报