C语言实现顺序表的基本操作

1.定义

线性表的顺序存储是指在内存中用一组地址连续的存储单元依次存储线性表的各元素,用这种存储形式存储的线性表称为顺序表。也就是说,顺序表以数据元素在计算机内的物理位置相邻来表示数据元素在线性表中的逻辑相邻关系。

2.线性表的顺序存储示意图

C语言实现顺序表的基本操作_第1张图片

3.代码体现

Seqlist.h
#ifndef __SEQLIST_H__
#define __SEQLIST_H__

#include 
#include
#include
#include

#define LIST_SIZE 10/*顺序表的的初始分配量*/
#define LIST_INCREMENT 2/*顺序表的分配增量*/
typedef int DateType;

typedef struct SeqList
{
    DateType* data;/*存储空间基址*/
    int length;/*当前长度*/
    int listsize;/*当前分配的存储容量(以sizeof(DateType))为单位*/
}SeqList,*pSeqList;
/*
SeqList就是所定义的顺序表的类型
pSeqList相当于SeqList*,指顺序表指针类型
*/
void InitSeqList(pSeqList pSeq);//初始化
void PushBack(pSeqList pSeq, DateType d);//尾部插入
void PrintSeqList(pSeqList pSeq);//打印
void PopBack(pSeqList pSeq);//删除尾部元素
void PushFront(pSeqList pSeq, DateType d);//头插元素
void PopFront(pSeqList pSeq);//头删元素
int Find(pSeqList pSeq,DateType d);//查找某一元素
void Insert(pSeqList pSeq, int pos, DateType d);//某一元素前插入

void Erase(pSeqList pSeq, int pos);//删除指定位置元素
void Remove(pSeqList pSeq, DateType d);//删除指定元素
void RemoveAll(pSeqList pSeq, DateType d);//删除所有指定元素
#endif //__SEQLIST_H__
Seqlist.c
#define _CRT_SECURE_NO_WARNINGS 1

#include"Seqlist.h"
void InitSeqList(pSeqList pSeq)
{/*
 顺序表的初始化操作就是为线性表分配一个预定义大小的数组空间,
 并将顺序表的当前长度(当前数据的个数sz)设为0。
 */
    assert(pSeq != NULL);
    pSeq->data = (DateType*)malloc(sizeof(DateType)*LIST_SIZE);
    if (!pSeq->data)
    {
        printf("OVERFLOW");/*存储分配失败*/
        return;
    }
    pSeq->length = 0;/*空表的长度为0*/
    pSeq->listsize = LIST_SIZE;/*初始存储容量*/
}

void PushBack(pSeqList pSeq, DateType d)
{
    //1.assert
    assert(pSeq != NULL);
    //2.判断满
    if (pSeq->length == LIST_SIZE)
    {
        printf("顺序表已满,无法插入\n");
        return;
    }
    //3.存储元素
    pSeq->data[pSeq->length] = d;
    pSeq->length++;
}

void PrintSeqList(pSeqList pSeq)
{
    /*把顺序表当为数组来打印*/
    int i = 0;
    assert(pSeq != NULL);
    if (pSeq->length == 0)
    {
        printf("顺序表为空\n");
        return;
    }
    for (i = 0; i < pSeq->length; i++)
    {
        printf("%d", pSeq->data[i]);
    }
    printf("\n");
}

void PopBack(pSeqList pSeq)
{
    assert(pSeq != NULL);
    if (pSeq->length == 0)
    {
        printf("顺序表为空,无法删除\n");
        return;
    }
    pSeq->length --;
}

void PushFront(pSeqList pSeq, DateType d)
{
    assert(pSeq != NULL);
    int i = 0;
    if (pSeq->length==LIST_SIZE)
    {
        printf("顺序表已满,无法插入\n");
        return;
    }
    //1.将原有数据后移
    for (i = pSeq->length-1; i >= 0; i--)
    {
        pSeq->data[i + 1] = pSeq->data[i];
    }
    //2.头部插入新元素
    pSeq->data[0] = d;
    pSeq->length++;
}

void PopFront(pSeqList pSeq)
{
    int i = 0;
    assert(pSeq != NULL);
    if (pSeq->length == 0)
    {
        printf("顺序表为空无法删除\n");
    }
    for (i = 0; i < pSeq->length - 1; i++)
    {
        pSeq->data[i] = pSeq->data[i + 1];
    }
    pSeq->length--;
}

int Find(pSeqList pSeq, DateType d)
{
    int i = 0;
    assert(pSeq != NULL);
    for (i = 0; i < pSeq->length; i++)
    {
        if (pSeq->data[i] == d)
        {
            return i;
        }
    }
    return -1;
}

void Insert(pSeqList pSeq, int pos, DateType d)
{
    DateType *newbase, *q, *p;
    int i = 0;
    assert(pSeq != NULL);
    assert(pos >= 0 && pos <= pSeq->length);
    if (pSeq->length == LIST_SIZE)/*当存储空间已满,增加分配*/
    {
        newbase = (DateType*)relloc((*pSeq).data, ((*pSeq).listsize + LIST_INCREMENT) * sizeof(DateType));
        if (!newbase)
        {
            printf("追加空间失败\n");
            return;
        }
        pSeq->data = newbase;/*新基址*/
        pSeq->listsize = pSeq->listsize + LIST_INCREMENT;/*增加存储容量*/
    }
    for (i = (pSeq->length) - 1; i >= pos; i--)/*元素后移*/
    {
        pSeq->data[i + 1] = pSeq->data[i];
    }
    pSeq->data[pos] = d;
    pSeq->length++;
}

void Erase(pSeqList pSeq, int pos)
{
    int i = 0;
    assert(pSeq != NULL);
    assert(pos >= 0 && pos <= pSeq->length);
    if (pSeq->length == 0)
    {
        printf("顺序表为空,无法删除\n");
    }
    for (i = pos; i < pSeq->length - 1; i++)
    {
        pSeq->data[i] = pSeq->data[i + 1];
    }
    pSeq->length--;
}

void Remove(pSeqList pSeq, DateType d)
{
    int i = 0;
    assert(pSeq != NULL);
    if (pSeq->length == 0)
    {
        printf("顺序表为空,不需要删除\n");
        return;
    }
    for (i = 0; i < pSeq->length; i++)
    {
        if (pSeq->data[i] == d)
        {
            break;
        }
    }
    //跳转到这有两种情况,1.找到了指定元素;2.遍历完整个顺序表未找到
    if (i == pSeq->length)
    {
        printf("删除的元素不存在\n");
        return;
    }
    for (; i < pSeq->length - 1; i++)//删除
    {
        pSeq->data[i] = pSeq->data[i + 1];
    }
    pSeq->length--;
}

void RemoveAll(pSeqList pSeq, DateType d)
{
    int i = 0;
    assert(pSeq != NULL);
    //if (pSeq->sz == 0)
    //{
    //  printf("顺序表为空,不需要删除\n");
    //  return;
    //}
    //for (i = 0; i < pSeq->sz; i++)
    //{
    //  if (pSeq->data[i] == d)
    //  {
    //      int j = 0;
    //      for (j = i; j < pSeq->sz-1; j++)//这种算法存在一个问题,连着的相同元素不能删除干净
    //      {
    //          pSeq->data[j] = pSeq->data[j + 1];
    //      }
    //      pSeq->sz--;
    //      --i;//消除这个问题
    //  }
    //}
    int count = 0;
    DateType *tmp = NULL;
    tmp = (DateType*)malloc(sizeof(DateType)*pSeq->length); /*申请一个临时空间*/
    for (i = 0; i < pSeq->length; i++)/*把原空间中的指定元素排除,其余元素拷贝到新空间*/
    {
        if (pSeq->data[i] != d)
        {
            tmp[count++] = pSeq->data[i];
        }
    }
    memcpy(pSeq->data, tmp, sizeof(DateType)*count);/*新空间存的是正确的元素,再将这些元素拷贝会原空间*/
    pSeq->length = count;
    free(tmp);
    tmp = NULL;
}

你可能感兴趣的:(数据结构--C语言版)