实现动态顺序表

头文件Seqlist.h中:
#pragma once
#include <assert.h>
#include <malloc.h>

typedef int DataType;
typedef struct SeqList
{
  DataType * _array;  //数据块指针
  size_t _size;  //当前的有效数据个数
  size_t _capacity;   //容量
}Seqlist;
//打印顺序表
void PrintSeqlist(Seqlist * pSeq)
{
  int i=0;
  assert(pSeq);
  for(;i<pSeq->_size;i++)
  {
    printf( "%d ",pSeq->_array[i]);
  }
  printf("\n");
}
//增大容量
void CheckCapacity(Seqlist * pSeq) 
{
  if(pSeq->_size>=pSeq->_capacity) 
  {
    DataType * tmp;
                pSeq->_capacity*=2;  //将空间扩大两倍
                tmp=(DataType *)malloc( sizeof(DataType)*(pSeq->_capacity));   //先暂时开辟一块扩大后的空间
                memcpy(tmp,pSeq->_array, sizeof(DataType)*(pSeq->_size));  //把原来的数据拷到tmp中

                free(pSeq->_array);  //释放之前的空间
                pSeq->_array=tmp;
  }
}
//初始化
void InitSeqlist(Seqlist * pSeq)
{
  assert(pSeq);
  pSeq->_capacity=3;  //先给3个大的容量
  pSeq->_array=(DataType *)malloc( sizeof(DataType)*(pSeq->_capacity));   //给其进行动态开辟空间
  pSeq->_size=0;  //刚开始没有有效的数据
}
//尾插入
void PushBack(Seqlist * pSeq,DataType x)
{
  assert(pSeq);
  CheckCapacity(pSeq);
  pSeq->_array[pSeq->_size]=x;
  pSeq->_size++;
}
//尾删除
void PopBack(Seqlist * pSeq)
{
  assert(pSeq);
  if(pSeq->_size==0)
  {
    printf("顺序表已空,无法再进行删除\n" );
                return;
  }
  pSeq->_size--;
}
//头插入
void PushFront(Seqlist * pSeq,DataType x)
{
  int i=( int)pSeq->_size;
  assert(pSeq);
  CheckCapacity(pSeq);
  for(;i>0;i--)
  {
    pSeq->_array[i]=pSeq->_array[i-1];
  }
  pSeq->_array[0]=x;
  pSeq->_size++;
}
//头删除
void PopFront(Seqlist * pSeq)
{
                int i=1;
  assert(pSeq);
  if(pSeq->_size==0)
  {
    printf( "顺序表已空,无法再进行删除\n" );
                return;
  }
  for(;i<( int)pSeq->_size;i++)
  {
    pSeq->_array[i-1]=pSeq->_array[i];
  }
  pSeq->_size--;
}
//中间任意位置插入
void Insert(Seqlist * pSeq,size_t pos,DataType x)
{
  int i=( int)pSeq->_size-1;
  assert(pSeq);
  assert(pos<=pSeq->_size);  //确保是在中间位置插入
  CheckCapacity(pSeq);
  for(;i>=( int)pos;i--)  //注意此处 int i(有符号数)与size_t pos(无符号数)之间的关系
  {
                  pSeq->_array[i+1]=pSeq->_array[i];
  }
  pSeq->_array[pos]=x;
  pSeq->_size++;
}
//删除某个位置上的数
void Erase(Seqlist * pSeq,size_t pos)
{
                int i=(int )pos+1;
  assert(pSeq);
  assert(pos<=pSeq->_size);
  if(pSeq->_size==0)
  {
    printf( "顺序表已空,无法再进行删除\n" );
                return;
  }
  for(;i<( int)pSeq->_size;i++)
  {
                  pSeq->_array[i-1]=pSeq->_array[i];
  }
  pSeq->_size--;
}
//删除其中第一次出现的某个数
void Remove(Seqlist * pSeq, DataType x)
{
                int i=0;
  assert(pSeq);
  for(;i<pSeq->_size;i++)  //从 i=0 这个位置开始找
  {
   if(pSeq->_array[i]==x)
                {
                 int begin=i;
                 for(;begin<(int )pSeq->_size-1;begin++)
                  {
                    pSeq->_array[begin]=pSeq->_array[begin+1];
                  }
                  pSeq->_size--;
                 return;
                }
  }
}
//删除其中出现的所有的 某个数
void RemoveAll(Seqlist *pSeq, DataType x)
{
  int count=0;
   size_t  firstIndex = 0,secondIndex = 0;
  assert(pSeq);
 while(secondIndex<pSeq->_size)
 {
  if(pSeq->_array[secondIndex]==x)
   {
     count++;   //找到后,对它进行计数,secondIndex后移一位
   }
  else  //没找到,则将pSeq->_arry[secondIndex]的值赋给pSeq->_array[firstIndex],同时firstIndex后移一位,secondIndex后移一位
   {
     pSeq->_array[firstIndex]=pSeq->_array[secondIndex]; 
                 firstIndex++;
   }
   secondIndex++;
  }
 pSeq->_size-=count;   //减去其中 出现的所有的某个数后 的长度
}
//查找其中的某个数,如果找到了,就返回其下标,没有找到就返回-1
int Find(Seqlist * pSeq, DataType x)
{
                int i=0;
  assert(pSeq);
  for(;i<pSeq->_size;i++)
  {
   if(pSeq->_array[i]==x)
                                return i;
  }
  if(i>=pSeq->_size)
  {
    printf( "没有找到这个数\n" ); 
                return -1;
  }
}
//修改某个下标的数
void Modify(Seqlist * pSeq,size_t pos,DataType x)
{
                int i=0;
                assert(pSeq);
                assert(pos<=pSeq->_size);
                for(;i<pSeq->_size;i++)
                {
                 if(i==pos)
                  {
                    pSeq->_array[i]=x;
                  }
                }
}

源文件(.c文件)中:
#include <stdio.h>
#include "Seqlist.h"

//尾插入测试
void test1()
{
  Seqlist s;
  InitSeqlist(&s);

  PushBack(&s,1);
  PushBack(&s,2);
  PushBack(&s,3);
  PushBack(&s,4);
  PushBack(&s,5);

  PrintSeqlist(&s);
}
//尾删除测试
void test2()
{
  Seqlist s;
  InitSeqlist(&s);

  PushBack(&s,1);
  PushBack(&s,2);
  PushBack(&s,3);
  PushBack(&s,4);
  PushBack(&s,5);

  PrintSeqlist(&s);

  PopBack(&s);  //尾删除一个
  PopBack(&s);  //再尾删除一个

  PrintSeqlist(&s);
}
//头插入测试
void test3()
{
  Seqlist s;
  InitSeqlist(&s);

  PushFront(&s,1);
  PushFront(&s,2);
  PushFront(&s,3);

  PrintSeqlist(&s);
}
//头删除测试
void test4()
{
  Seqlist s;
  InitSeqlist(&s);

  PushFront(&s,1);
  PushFront(&s,2);
  PushFront(&s,3);
  PushFront(&s,4);

  PrintSeqlist(&s); 

  PopFront(&s);  //头删除一次
  //PopFront(&s);   //再头删除一次

  PrintSeqlist(&s);
}
//中间任意位置插入测试
void test5()
{
  Seqlist s;
  InitSeqlist(&s);

  PushFront(&s,1);
  PushFront(&s,2);
  PushFront(&s,3);
  PushFront(&s,4);

  PrintSeqlist(&s);  // 4 3 2 1

  Insert(&s,2,5);
  Insert(&s,2,6);
  Insert(&s,2,7);

  PrintSeqlist(&s);   // 4 3 7 6 5 2 1
}
//删除某个位置上的数
void test6()
{
  Seqlist s;
  InitSeqlist(&s);

  PushFront(&s,1);
  PushFront(&s,2);
  PushFront(&s,3);
  PushFront(&s,4);

  PrintSeqlist(&s);  // 4 3 2 1

  Erase(&s,2);  //删除下标为2的这个数
  Erase(&s,1);  //删除下标为1的这个数

  PrintSeqlist(&s);
}
//删除其中第一次出现的某个数测试
void test7()
{
  Seqlist s;
  InitSeqlist(&s);
 
  PushBack(&s,1);
  PushBack(&s,2);
  PushBack(&s,3);
  PushBack(&s,2);
  PushBack(&s,2);
  PushBack(&s,4);

  PrintSeqlist(&s);

  Remove(&s,2);

  PrintSeqlist(&s);
}
//删除其中出现的所有的 某个数测试
void test8()
{
  Seqlist s;
  InitSeqlist(&s);

  PushBack(&s,1);
  PushBack(&s,2);
  PushBack(&s,3);
  PushBack(&s,2);
  PushBack(&s,2);
  PushBack(&s,4);

  PrintSeqlist(&s);

  RemoveAll(&s,2);

  PrintSeqlist(&s);
}
//查找其中的某个数,如果找到了,就返回其下标,没有找到就返回-1
void test9()
{
                int ret=0;
  Seqlist s;
  InitSeqlist(&s);

  PushBack(&s,1);
  PushBack(&s,2);
  PushBack(&s,3);
  PushBack(&s,2);
  PushBack(&s,2);
  PushBack(&s,4);

  PrintSeqlist(&s);  // 1 2 3 2 2 4

  ret=Find(&s,2);
  printf("%d\n",ret);
}
//修改某个下标的数
void test10()
{
  Seqlist s;
  InitSeqlist(&s);

  PushBack(&s,1);
  PushBack(&s,2);
  PushBack(&s,3);
  PushBack(&s,2);
  PushBack(&s,2);
  PushBack(&s,4);

  PrintSeqlist(&s);   // 1 2 3 2 2 4

  Modify(&s,3,5);  //把下标为3的数(2)改成5

  PrintSeqlist(&s);   // 1 2 3 5 2 4
}
int main()
{
                //test1();
                //test2();
                //test3();
                //test4();
                //test5();
                //test6();
                //test7();
                //test8();
                //test9();
                test10();
                system( "pause");
  return 0;
}


本文出自 “追寻内心的声音” 博客,转载请与作者联系!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的动态顺序表实现,包括插入、删除、查找、遍历等基本操作: ```c #include <stdio.h> #include <stdlib.h> #define INIT_CAPACITY 10 // 初始容量 #define INCREMENT 5 // 每次扩容增加的容量 typedef struct { int *data; // 数据 int length; // 当前长度 int capacity; // 当前容量 } SeqList; // 初始化顺序表 void init(SeqList *list) { list->data = (int*)malloc(INIT_CAPACITY * sizeof(int)); list->length = 0; list->capacity = INIT_CAPACITY; } // 扩容 void expand(SeqList *list) { list->capacity += INCREMENT; list->data = (int*)realloc(list->data, list->capacity * sizeof(int)); } // 插入元素 void insert(SeqList *list, int index, int value) { if (index < 0 || index > list->length) { printf("Index out of bounds\n"); return; } if (list->length == list->capacity) { expand(list); } for (int i = list->length - 1; i >= index; i--) { list->data[i+1] = list->data[i]; } list->data[index] = value; list->length++; } // 删除元素 void remove(SeqList *list, int index) { if (index < 0 || index >= list->length) { printf("Index out of bounds\n"); return; } for (int i = index; i < list->length - 1; i++) { list->data[i] = list->data[i+1]; } list->length--; } // 查找元素 int find(SeqList *list, int value) { for (int i = 0; i < list->length; i++) { if (list->data[i] == value) { return i; } } return -1; } // 遍历顺序表 void traverse(SeqList *list) { for (int i = 0; i < list->length; i++) { printf("%d ", list->data[i]); } printf("\n"); } int main() { SeqList list; init(&list); insert(&list, 0, 1); insert(&list, 0, 2); insert(&list, 2, 3); remove(&list, 1); traverse(&list); return 0; } ``` 在这个实现中,顺序表的容量会在需要时自动扩容,每次扩容增加的容量为 `INCREMENT`。可以根据实际需求修改这个值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值