实现动态顺序表

头文件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;
}


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

你可能感兴趣的:(顺序表)