动态顺序表的实现

动态顺序表的实现,是基于静态顺序表而实现的。将原来静态顺序表中静态定义的数组,改为用来动态定义,从而减少内存的开销,,增大程序的运行效率。
代码实现如下:

**sequence.h**
#ifndef __SEQU_H__
#define __SEQU_H__
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#define DEFAULT_SZ 2
#define INC 2
typedef int TypeData;

typedef struct Seqlist
{
    TypeData *data;
    int sz;
    int capacity;//定义容量
}Seqlist, *pSeqlist;

void Initseqlist(pSeqlist ps);
void PushBack(pSeqlist ps, TypeData d);
void Display(pSeqlist ps);
void PopBack(pSeqlist ps);
void PushFront(pSeqlist ps, TypeData d);
void PopFront(pSeqlist ps);
int Find(pSeqlist ps, TypeData d);
void Remove(pSeqlist ps, TypeData d);
void RemoveAll(pSeqlist ps, TypeData d);
void Insert(pSeqlist ps, TypeData d, int pos);
void Reverse(pSeqlist ps);
void Sort(pSeqlist ps);
int BinarySearch(pSeqlist ps, TypeData d);
void Destroy(pSeqlist ps);

#endif//__SEQU_H__
**sequence.c**
#define _CRT_SECURE_NO_WARNINGS 1
#include "sequence.h"
void Initseqlist(pSeqlist ps)
{
    assert(ps != NULL);
    ps->sz = 0;
    ps->capacity = DEFAULT_SZ;
    ps->data = malloc(sizeof(TypeData)*(ps->capacity));
    if (ps->data == NULL)
    {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    memset(ps->data, 0, sizeof(TypeData)*(ps->capacity));
}

void Checkcap(pSeqlist ps)//扩容
{
    assert(ps != NULL);
    if (ps->sz == ps->capacity)
    {
        TypeData*ptr = realloc(ps->data, 
            (ps->capacity + INC)*sizeof(TypeData));
            if (ptr != NULL)
            {
                ps->data = ptr;
                ps->capacity += INC;//表个数
            }
            else
            {
                perror("realloc");
                exit(EXIT_FAILURE);
            }
    }
}

void PushBack(pSeqlist ps, TypeData d)
{
    assert(ps != NULL);
    Checkcap(ps);//扩容
    assert(ps->data != NULL);
    ps->data[ps->sz] = d;
    ps->sz++;
}

void Display(pSeqlist ps)
{
    assert(ps != NULL);
    int i = 0;
    for (i = 0; i < ps->sz; i++)
    {
        printf("%d ", ps->data[i]);
    }
    printf("\n");
}

void PopBack(pSeqlist ps)
{
    assert(ps != NULL);
    if (ps->sz == 0)
    {
        return;
    }
    ps->sz--;
}

void PushFront(pSeqlist ps, TypeData d)
{
    assert(ps != NULL);
    int i = 0;
    Checkcap(ps);//扩容
    assert(ps->data != NULL);
    memmove(ps->data + 1, ps->data, sizeof(TypeData)*(ps->sz));
    /*for (i = ps->sz; i > 0; i--)
    {
        ps->data[i] = ps->data[i-1];
    }*/
    /*void *memmove( void *dest, const void *src, size_t count );*/  //memmove的原型

    ps->data[0] = d;
    ps->sz++;
}

void PopFront(pSeqlist ps)
{
    int i = 0;
    assert(ps != NULL);
    if (ps->sz == 0)
    {
        return;
    }
    for (i = 0; i < ps->sz; i++)
    {
        ps->data[i] = ps->data[i + 1];
    }
    ps->sz--;
}

int Find(pSeqlist ps, TypeData d)
{
    int i = 0;
    for (i = 0; i < ps->sz - 1; i++)
    {
        if (d == ps->data[i])
        {
            return i;
        }
    }
    return -1;
}


void Remove(pSeqlist ps, TypeData d)
{
    assert(ps != NULL);
    int pos = 0;
    int i = 0;
    pos = Find(ps, 1);
    if (pos != -1)
    {
        for (i = 0; i < ps->sz; i++)
        {
            ps->data[i] = ps->data[i + 1];
        }
    }
    ps->sz--;
}

void RemoveAll(pSeqlist ps, TypeData d)//tiao
{
    assert(ps != NULL);
    int i = 0;
    for (i = 0; i < ps->sz; i++)
    {
        if (d == ps->data[i])
        {
            ps->data[i] = ps->data[i + 1];
            ps->sz--;
        }
    }

}

void Insert(pSeqlist ps, TypeData d, int pos)
{
    assert(ps != NULL);
    int i = 0;
    Checkcap(ps);//扩容
    assert(ps->data != NULL);
    /*for (i = ps->sz; i > pos; i--)         //两种实现方式
    {
    ps->data[i] = ps->data[i - 1];
    }*/
    memmove(ps->data + pos + 1, ps->data + pos, sizeof(TypeData)*(ps->sz - pos));
    ps->data[pos] = d;
    ps->sz++;
}

void Reverse(pSeqlist ps)
{
    TypeData tmp = 0;
    TypeData *left = ps->data;
    TypeData *right = ps->data + (ps->sz) - 1;
    while (left < right)
    {
        tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}

void Sort(pSeqlist ps)//冒泡排序
{
    int i = 0;
    int j = 0;
    for (i = 0; i < ps->sz - 1; i++)
    {
        for (j = 0; j < ps->sz - i - 1; j++)
        {
            if (ps->data[j]>ps->data[j + 1])//升序
            {
                TypeData tmp = ps->data[j];
                ps->data[j] = ps->data[j + 1];
                ps->data[j + 1] = tmp;
            }
        }
    }
}

int BinarySearch(pSeqlist ps, TypeData d)
{
    int left = 0;
    int right = ps->sz - 1;
    while (left <= right)  //在等于之时,未使其进来,所以没有进来判断
    {
        int mid = left + (right - left) / 2;
        if (ps->data[mid]>d)
        {
            right = mid - 1;
        }
        else if (ps->data[mid] < d)
        {
            left = mid + 1;
        }
        else
        {
            return mid;
        }
    }
    return -1;//没找到
    //表示循环结束,,return的含义便是,只要找到,则直接结束程序
}


void Destroy(pSeqlist ps)//销毁动态开辟的内存
{
    assert(ps != NULL);
    free(ps->data);
    ps->data = NULL;
    ps->capacity = 0;
    ps->sz = 0;
}

测试代码如下:

**test.c**
#define _CRT_SECURE_NO_WARNINGS 1
#include "sequence.h"
void menu()
{
    printf("***********************\n");
    printf("****    1 Test1   ****\n");
    printf("****    2 Test2   ****\n");
    printf("****    3 Test3   ****\n");
    printf("****    4 Test4   ****\n");
    printf("****    5 Test5   ****\n");
    printf("****    0 Exit    *****\n");
}

void Test1()
{
    Seqlist my_list;
    Initseqlist(&my_list);
    PushBack(&my_list,1);//从尾部插入
    PushBack(&my_list,2);
    PushBack(&my_list,3);
    PushBack(&my_list, 5);
    PushBack(&my_list,4);
    Display(&my_list);//显示

    PopBack(&my_list);//从尾部删除
    Display(&my_list);
    PopBack(&my_list);
    Display(&my_list);
    PopBack(&my_list);
    Display(&my_list);
    PopBack(&my_list);
    Display(&my_list);
    PopBack(&my_list);
    Display(&my_list);
}
void Test2()
{
    Seqlist my_list;
    Initseqlist(&my_list);
    PushFront(&my_list, 1);//从头部插入
    PushFront(&my_list, 2);
    PushFront(&my_list, 3);
    PushFront(&my_list, 4);
    Display(&my_list);

    PopFront(&my_list);//从头部删除
    Display(&my_list);
    PopFront(&my_list);
    Display(&my_list);
    PopFront(&my_list);
    Display(&my_list);
    PopFront(&my_list);
    Display(&my_list);
    PopFront(&my_list);
    Display(&my_list);
}

void Test3()
{
    Seqlist my_list;
    Initseqlist(&my_list);
    PushFront(&my_list, 1);//从头部插入
    PushFront(&my_list, 2);
    PushFront(&my_list, 3);
    PushFront(&my_list, 4);
    Display(&my_list);

    int ret = Find(&my_list, 1);//查找某个函数
    printf("%d\n", ret);

    Remove(&my_list, 1);//删除指定位置的元素
    RemoveAll(&my_list, 1);//删除指定元素
    Display(&my_list); 
}   
void Test4()
{
    Seqlist my_list;
    Initseqlist(&my_list);
    PushBack(&my_list,1);//从尾部插入
    PushBack(&my_list,2);
    PushBack(&my_list,3);
    PushBack(&my_list, 5);
    PushBack(&my_list,4);
    Display(&my_list);//显示
    Insert(&my_list, 6, 2);//插入
    Display(&my_list);
    Reverse(&my_list);//逆序
    Display(&my_list);
}
void Test5()
{
    Seqlist my_list;
    Initseqlist(&my_list);
    PushBack(&my_list,1);//从尾部插入
    PushBack(&my_list,2);
    PushBack(&my_list,3);
    PushBack(&my_list, 5);
    PushBack(&my_list,4);
    Display(&my_list);//显示
    Sort(&my_list);//排序
    Display(&my_list);
    int tmp = BinarySearch(&my_list,2);//二分查找
}

int main()
{
    int input = 0;
    do{
        menu();
        printf("请选择: ");
        scanf("%d", &input);
        switch (input)
        {
        case 0:
            break;
        case 1:
            Test1();
            break;
        case 2:
            Test2();
            break;
        case 3:
            Test3();
            break;
        case 4:
            Test4();
            break;
        case 5:
            Test5();
            break;
        default:
            break;
        }
    } while (input);
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值