码迷,mamicode.com
首页 > 编程语言 > 详细

【C语言】静态顺序表和动态顺序表的实现

时间:2015-06-30 10:53:58      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:

静态顺序表

定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识。只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作。

有两种定义顺序表的方法:一是静态地定义一张顺序表;二是动态地生成一张顺序表。

静态地定义一张顺序表的方法与定义一个数组的方法类似。可以描述如下:

#define MAX_SIZE 100
typedef int DataType;
typedef struct SeqList
{
    DataType array[MAX_SIZE];
    size_t size;
}SeqList;

静态顺序表的一些与运算实现如下:


SeqList.h

#pragma once
#define _SEQ_LIST_
#ifdef _SEQ_LIST_

#include <stdio.h>
#include <string.h>//memset
#include <assert.h>//assert

#define MAX_SIZE 100
typedef int DataType;
typedef struct SeqList
{
    DataType array[MAX_SIZE];
    size_t size;
}SeqList;

typedef enum TAG
{
    TURE,//找到对应元素
    FALSE,//未找到对应元素
}TAG;
TAG tag;
typedef struct FindRet
{
    TAG IsFind;//反应是否找到对应的元素
    size_t index;//找到的元素的下标
}FindRet;
FindRet ret;
void InitSeqList(SeqList* pSeq);//初始化
void PrintSeqList(SeqList* pSeq);//显示数据
void ExplandCapicity(SeqList *pSeq);//扩大容量

void PushBack(SeqList* pSeq, DataType x);//从尾插入数据
void PopBack(SeqList* pSeq);//从尾删除数据

void PushFront(SeqList* pSeq, DataType x);//从头插入数据
void PopFront(SeqList* pSeq);//从头删除数据

void Insert(SeqList* pSeq, size_t index, DataType x);//在下标为index处插入数据
void Modified(SeqList* pSeq, size_t index, DataType x);//修改下标为index的数据为x
void Removed(SeqList* pSeq, size_t index);//删除下标为index的数据

FindRet Find(SeqList *pSeq, DataType x, size_t index);//查找数据
TAG Erase(SeqList *pSeq, DataType x, TAG all);//all=FALSE时删除第一个出现的数据
                                             //all=TURE时删除一个所有相同的数据
#endif

SeqList.c

#include "seqlist.h"
void InitSeqList(SeqList *pSeq)//初始化
{
    assert(pSeq);
    memset(pSeq->array, 0,MAX_SIZE*sizeof(DataType));
    pSeq->size = 0;
}
void PrintSeqList(SeqList* pSeq)//显示数据
{
    size_t i = 0;
    assert(pSeq);
    for (i = 0; i < pSeq->size; i++)
    {
        printf("%d ", pSeq->array[i]);
    }
}
void PushBack(SeqList* pSeq, DataType x)//从尾插入数据
{
    assert(pSeq);
    if (pSeq->size > MAX_SIZE-1)
    {
        printf("The seqlist is Full\n");
        return;
    }
    pSeq->array[pSeq->size++] = x;
}
void PopBack(SeqList* pSeq)//从尾删除数据
{
    assert(pSeq);
    if (pSeq->size < 1)
    {
        printf("The seqlist is empty\n");
        return;
    }
    --pSeq->size;
    //或者pSeq->array[--pSeq->size] = 0;
}
void PushFront(SeqList* pSeq, DataType x)//从头插入数据
{ 
    int i = pSeq->size-1;
    assert(pSeq);
    if (pSeq->size > MAX_SIZE-1)
    {
        printf("The seqlist is Full\n");
        return;
    }
    for (; i >= 0; i--)
    {
        pSeq->array[i+1] = pSeq->array[i];
    }
    pSeq->array[0] = x;
    pSeq->size++;
}
void PopFront(SeqList* pSeq)//从头删除数据
{
    size_t i = 0;
    assert(pSeq);
    if (pSeq->size < 1)
    {
        printf("The seqlist is empty\n");
        return;
    }
    for (i = 0; i < pSeq->size - 1; i++)
    {
        pSeq->array[i] = pSeq->array[i + 1];
    }
    pSeq->size--;
}
void Insert(SeqList* pSeq, size_t index, DataType x)//在index处随机插入数据
{
    size_t i = pSeq->size;
    assert(pSeq);
    if (index > MAX_SIZE-1)
    {
        printf("The seqlist is Full\n");
        return;
    }
    for (; i > index; i--)
    {
        pSeq->array[i] = pSeq->array[i-1];
    }
    pSeq->array[index] = x;
    pSeq->size++;
}
void Modified(SeqList* pSeq, size_t index, DataType x)//随机修改数据(修改index处的值)
{
    assert(pSeq);
    assert(index<pSeq->size);
    pSeq->array[index] = x;
}
void Removed(SeqList* pSeq, size_t index)//随机删除数据
{
    size_t i = index;
    assert(pSeq);
    assert(index<pSeq->size);
    for (; i < pSeq->size - 1; i++)
    {
        pSeq->array[i] = pSeq->array[i + 1];
    }
    pSeq->size--;
}
FindRet Find(SeqList *pSeq, DataType x,size_t index)//增加了形参index,可以记录每次查找的
{                                                   //位置,提高了效率
    assert(pSeq);
    ret.IsFind = FALSE;
    for (; index < pSeq->size; index++)
    {
        if (pSeq->array[index] == x)
        {
            ret.index = index;
            ret.IsFind = TURE;
            return ret;
        }
    }
    return ret;
}
TAG Erase(SeqList *pSeq, DataType x,TAG all)//all=FALSE表示删除一个第一次出现的数据
{                                           //all=TRUE表示删除一个重复的数据
    assert(pSeq);
    TAG success = FALSE;
    ret = Find(pSeq,x,0);
    while (ret.IsFind == TURE)
    {
        success = TURE;
        Removed(pSeq,ret.index);
        if (all == TURE)//表示删除一个数据
        {
            break;
        }
        ret = Find(pSeq,x,ret.index);
    }
    return success;
}
void Test()
{
    SeqList s;
    InitSeqList(&s);
    printf("The PushBack is:\n");
    PushBack(&s, 3);
    PushBack(&s ,5);
    PushBack(&s, 4);
    PushBack(&s, 3);
    PushBack(&s, 2);
    PushBack(&s, 3);
    PushBack(&s, 3);
    PushBack(&s, 3);
    PushBack(&s, 1);
    PrintSeqList(&s);
    printf("\nPopBack is:\n");
    PopBack(&s);
    PrintSeqList(&s);
    printf("\nPushFront 10,20 is:\n");
    PushFront(&s,10);
    PushFront(&s,20);
    PrintSeqList(&s);
    printf("\nPopFront 20 is:\n");
    PopFront(&s);
    PrintSeqList(&s);
    printf("\nInsert 99 is:\n");
    Insert(&s,2,99);
    PrintSeqList(&s);
    printf("\nModified 99 to 88 is :\n");
    Modified(&s,2,88);
    PrintSeqList(&s);
    printf("\nremoved 88 is:\n");
    Removed(&s, 2);
    PrintSeqList(&s);
    printf("\nFind %d index is :\n",5);
    ret = Find(&s, 5,0);
    if (ret.IsFind == TURE)
    {
        printf("%d\n",ret.index);
    }
    else if (ret.IsFind == FALSE)
    {
        printf("is not exit\n");
    }
    printf("Erase 3 is :\n");
    Erase(&s,3,FALSE);
    PrintSeqList(&s);
}
int main()
{
    Test();
    return 0;
}

技术分享


动态地生成一张顺序表的方法可描述如下:

#define EXPLANDSIZE 2
typedef int DataType;
typedef struct SeqList
{
    DataType *elem;//指向当前空间
    size_t size;//当前有效数据的长度
    size_t capicity;//当前容量
}SeqList;

动态顺序表的一些与运算实现如下:


SeqList.h


#pragma once
#define _SEQ_LIST_
#ifdef _SEQ_LIST_

#include <stdio.h>//size_t
#include <stdlib.h>//malloc
#include <assert.h>//assert
#include <string.h>//memcpy

#define EXPLANDSIZE 2
typedef int DataType;
typedef struct SeqList
{
    DataType *elem;//指向当前空间
    size_t size;//当前有效数据的长度
    size_t capicity;//当前容量
}SeqList;

typedef enum TAG
{
    TURE,
    FALSE,
}TAG;
TAG tag;
typedef struct FindRet
{
    TAG Isfind;
    size_t index;
}FindRet;
FindRet ret;
void InitSeqList(SeqList* pSeq);//初始化
void PrintSeqList(SeqList* pSeq);//显示数据
void ExplandCapicity(SeqList *pSeq);//扩大容量

void PushBack(SeqList* pSeq, DataType x);//从尾插入数据
void PopBack(SeqList* pSeq);//从尾删除数据

void PushFront(SeqList* pSeq, DataType x);//从头插入数据
void PopFront(SeqList* pSeq);//从头删除数据

void Insert(SeqList* pSeq, size_t index, DataType x);//在下标为index处插入数据
void Modified(SeqList* pSeq, size_t index, DataType x);//修改下标为index的数据为x
void Removed(SeqList* pSeq, size_t index);//删除下标为index的数据

FindRet Find(SeqList *pSeq, DataType x,size_t index);//查找数据
TAG Erase(SeqList *pSeq, DataType x,TAG all);//all=FALSE时删除第一个出现的数据
                                             //all=TURE时删除一个所有相同的数据
void BubbleSort(SeqList *pSeq);//冒泡排序
void SeleSort(SeqList *pSeq);//选择排序
void swap(DataType *left,DataType *right);//交换值
FindRet BinarySearch(SeqList *pSeq, DataType X);//二分查找
#endif

SeqList.c

#include "seqListdongtai.h"

void InitSeqList(SeqList* pSeq)//初始化
{
    assert(pSeq);
    pSeq->elem = (DataType *)malloc(EXPLANDSIZE * sizeof(DataType));
    pSeq->capicity = EXPLANDSIZE;
    pSeq->size = 0;//表示有效数据
}
void ExplandCapicity(SeqList *pSeq)
{
    if (pSeq->size == pSeq->capicity)
    {
        //pSeq->capicity += ExplandSize;
        //DataType *newbase = (DataType *)malloc(pSeq->capicity * sizeof(DataType));
        DataType *newbase = (DataType *)malloc(pSeq->capicity*2 * sizeof(DataType));
        pSeq->capicity *= 2;
        memcpy(newbase, pSeq->elem, pSeq->size * sizeof(DataType));
        free(pSeq->elem);
        pSeq->elem = newbase;
    }
}
FindRet Find(SeqList *pSeq, DataType x, size_t index)//查找数据
{
    assert(pSeq);
    assert(index<pSeq->size);
    ret.Isfind = FALSE;
    for (; index < pSeq->size; index++)
    {
        if (pSeq->elem[index] == x)
        {
            ret.index = index;
            ret.Isfind = TURE;
            return ret;
        }
    }
    return ret;
}

void PrintSeqList(SeqList* pSeq)//显示数据
{
    assert(pSeq);
    size_t i = 0;   
    for (; i < pSeq->size; i++)
    {
        printf("%d ",pSeq->elem[i]);
    }
}
void PushBack(SeqList* pSeq, DataType x)//从尾插入数据
{
    assert(pSeq);
    ExplandCapicity(pSeq);
    pSeq->elem[pSeq->size++] = x;
}
void PopBack(SeqList* pSeq)//从尾删除数据
{
    assert(pSeq);
    if (pSeq->size > 0)
    {
        pSeq->size--;
    }
}
void PushFront(SeqList* pSeq, DataType x)//从头插入数据
{
    assert(pSeq);
    size_t i = pSeq->size;  
    ExplandCapicity(pSeq);
    for (; i > 0; i--)
    {
        pSeq->elem[i] = pSeq->elem[i - 1];
    }
    pSeq->elem[0] = x;
    pSeq->size++;
}
void PopFront(SeqList* pSeq)//从头删除数据
{
    assert(pSeq);
    assert(pSeq->size != 0);
    size_t i = 0;   
    for (; i < pSeq->size - 1; i++)
    {
        pSeq->elem[i] = pSeq->elem[i + 1];
    }
    pSeq->size--;
}
void Insert(SeqList* pSeq, size_t index, DataType x)//随机插入数据
{
    assert(pSeq);
    assert(index<pSeq->size);
    size_t i = pSeq->size;  
    ExplandCapicity(pSeq);
    for (; i > index; i--)
    {
        pSeq->elem[i] = pSeq->elem[i - 1];
    }
    pSeq->elem[index] = x;
    pSeq->size++;
}
void Modified(SeqList* pSeq, size_t index, DataType x)//随机修改数据
{
    assert(pSeq);
    assert(index<pSeq->size);
    pSeq->elem[index] = x;
}
void Removed(SeqList* pSeq, size_t index)//随机删除数据
{
    assert(pSeq);
    assert(index<pSeq->size);
    size_t i = index;
    for (; i < pSeq->size-1; i++)
    {
        pSeq->elem[i] = pSeq->elem[i + 1];
    }
    pSeq->size--;
}
TAG Erase(SeqList *pSeq, DataType x, TAG all)//删除一个所有相同的数据
{
    assert(pSeq);
    tag = FALSE;
    ret = Find(pSeq,5,0);
    while (ret.Isfind == TURE)
    {
        tag = TURE;
        Removed(pSeq,ret.index);
        if (all == FALSE)
        {
            break;
        }
        ret = Find(pSeq,5,ret.index);
    }
    return tag;
}
void swap(DataType *left, DataType *right)//交换值
{
    DataType tmp = *left;
    *left = *right;
    *right = tmp;
}
void BubbleSort(SeqList *pSeq)//冒泡排序
{
    int flag = 0,count = 0;
    size_t index = 0,end = 0;
    assert(pSeq);
    for (index = 0; index < pSeq->size - 1; index++)//循环比较
    {
        for (end = 0; end < (pSeq->size - 1) - index; end++)
        {
            count++;
            if (pSeq->elem[end] > pSeq->elem[end + 1])
            {
                int tmp = pSeq->elem[end];
                pSeq->elem[end] = pSeq->elem[end + 1];
                pSeq->elem[end + 1] = tmp;
                flag = 1;
            }
        }
        if (flag == 0)
        {
            break;
        }
        flag = 0;
    }
    printf("冒泡次数:%d\n", count);
}
void SeleSort(SeqList *pSeq)//选择排序
{
    size_t index,minindex = 0;
    size_t begin = 0;
    for (begin = 0; begin < pSeq->size - 1;begin++)
    {
        minindex = begin;
        for (index = begin+1; index < pSeq->size; index++)
        {
            if (pSeq->elem[index] < pSeq->elem[minindex])
            {
                minindex = index;
            }
        }
        if (minindex != index)
        {
            swap(pSeq->elem + minindex, pSeq->elem + begin);
        }
    }
}
FindRet BinarySearch(SeqList *pSeq, DataType x)//二分查找
{
    assert(pSeq);
    int left, right, mid;
    left = 0;
    right = pSeq->size - 1;
    ret.Isfind = FALSE;
    while (left <= right)
    {
        mid = left +((right-left) / 2);
        if (pSeq->elem[mid] == x)
        {
            ret.Isfind = TURE;
            ret.index = mid;
            return ret;
        }
        else if (pSeq->elem[mid] < x)
        {
            left = mid + 1;
        }
        else
        {
            right = mid - 1;
        }
    }
    return ret;
}
int main()
{
    SeqList s;
    InitSeqList(&s);//初始化
    printf("PushBack is\n");
    PushBack(&s, 6);//从尾插入数据
    PushBack(&s, 5);
    PushBack(&s, 4);
    PushBack(&s, 5);
    PushBack(&s, 5);
    PushBack(&s, 3);
    PushBack(&s, 5);
    PushBack(&s, 2);
    PushBack(&s, 1);
    PrintSeqList(&s);
    printf("\nPopBack 1 is :\n");
    PopBack(&s);//从尾删除数据
    PrintSeqList(&s);
    printf("\nPushFront 99 is:\n");
    PushFront(&s,99);//从前插入数据
    PrintSeqList(&s);
    printf("\nPopFront 99 is:\n");
    PopFront(&s);//从前删除数据
    PrintSeqList(&s);
    printf("\nInsert 88 is:\n");
    Insert(&s,1,88);//在下标为1的地方插入数据
    PrintSeqList(&s);
    printf("\nModified 5 is :\n");
    Modified(&s,2,55);//修改下标为2的的数据为55
    PrintSeqList(&s);
    printf("\nRemove 4 is:\n");
    Removed(&s,3);//删除下标为3的数据
    PrintSeqList(&s);
    printf("\nErase 5 is:\n");
    Erase(&s,5,TURE);//删除所有5
    PrintSeqList(&s);
    printf("\nBubbleSort:\n");
    BubbleSort(&s);//冒泡排序
    PrintSeqList(&s);
    printf("\n");
    BubbleSort(&s);//再次冒泡排序
    PrintSeqList(&s);
    printf("\nSeleSort:\n");
    SeleSort(&s);//选择排序
    PrintSeqList(&s);
    printf("\nBinarySearch 88 is :\n");
    BinarySearch(&s, 88);//二分查找
    if (ret.Isfind == TURE)
    {
        printf("下标为:%d\n",ret.index);
    }
    else
    {
        printf("Search is failed\n");
    }
    return 0;
}

技术分享


线性表优点是:

无须为表示表中元素之间的逻辑关系增加额外的存储空间;

可以方便地随机访问表中任一位置的元素。

缺点是:

插入和删除运算不方便,除表尾的位置外,在表的其他位置上进行插入或删除操作都必须移动大量元素,其效率较低;

由于数组要求占用连续的存储空间,存储分配只能预先进行静态分配。因此,当表长变化较大时,难以确定数组的合适的大小。确定大了将造成浪费。

版权声明:本文为博主原创文章,未经博主允许不得转载。

【C语言】静态顺序表和动态顺序表的实现

标签:

原文地址:http://blog.csdn.net/sulijuan66/article/details/46685779

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!