顺序表的增删查改&&各类排序问题

来源:互联网 发布:取英文名字的软件 编辑:程序博客网 时间:2024/06/06 02:59

一,静态顺序表增删查改

#define MAX_SIZE 10  typedef int DataType;  typedef struct SeqList  {      DataType array[MAX_SIZE];      size_t size;  }SeqList;void Print(SeqList* seq)  {      assert(seq);      for (size_t i = 0; i <(seq->size); i++)      {          printf("%d ", seq->array[i]);      }      printf("\n");  }  void InitSeqList(SeqList* seq)  {      assert(seq);      memset(seq->array, 0, sizeof(DataType)*(MAX_SIZE));      seq->size = 0;  }  void DestorySeqList(SeqList* seq)  {      assert(seq);      seq->size = 0;  }  void PushBack(SeqList* seq, DataType x)  {      assert(seq);      if (seq->size >= MAX_SIZE)      {          printf("The SeqLIst is full\n");          return;      }      seq->array[seq->size] = x;      seq->size++;  }  void PopBack(SeqList* seq)  {      assert(seq);      if (seq->size <= 0)      {          printf("The SeqList is empty\n");          return;      }      seq->size--;  }  void PushFront(SeqList* seq, DataType x)  {      assert(seq);      if (seq->size >= MAX_SIZE)      {          printf("The SeqLIst is full\n");          return;      }      int end = seq->size;      while (end >= 0)      {          seq->array[end] = seq->array[end-1];          end--;      }      seq->size++;      seq->array[0] = x;  }  void PopFront(SeqList* seq)  {      assert(seq);      if (seq->size <= 0)      {          printf("The SeqList is empty\n");          return;      }      for (size_t i = 0; i < seq->size - 1; i++)      {          seq->array[i] = seq->array[i + 1];      }      seq->size--;  }  void Insert(SeqList* seq,size_t pos,DataType x){    assert(seq);    assert(pos>0);    assert(pos<=seq->size);    if(seq->size>= MAX_SIZE)    {        printf("The SeqList is full\n");        return;    }    int end = seq->size;    while(end>=pos)    {        seq->array[end+1]=seq->array[end];        end--;    }    seq->array[pos] = x;    seq->size++;}int Find(SeqList* seq, DataType x) {    assert(seq);    for(size_t i= 0;i<seq->size;i++)    {        if(seq->array[i]==x)        {            return i+1;        }    }    return -1;}void Earse(SeqList* seq,size_t pos){    assert(seq);    assert(pos>0);    assert(pos<=seq->size);    if(seq->size<=0)    {        printf("The SeqList is empty\n");        return;    }    for(size_t i = pos-1;i<seq->size-1;i++)    {        seq->array[i]=seq->array[i+1];    }    seq->size--;}void Remove(SeqList* seq, DataType x) {    assert(seq);    if(seq->size<=0)    {        printf("The SeqList is empty\n");        return;    }    int pos = Find(seq,x);    Earse(seq,pos);}void RemoveAll(SeqList* seq, DataType x)  {    assert(seq);    for(size_t i=0;i<seq->size;i++)    {        if(seq->array[i] == x)        {            for(size_t j=i;j<seq->size;j++)            {                seq->array[j]=seq->array[j+1];            }            seq->size--;        }    }}

二,排序问题

(1)冒泡排序

冒泡排序是交换排序中一种简单的排序方法。它的基本思想是对所有相邻记录的关键字值进行比效,如果是逆序(a[j]>a[j+1]),则将其交换,最终达到有序化。

void BubbleSort(SeqList* seq)//冒泡排序{    assert(seq);    if(seq->size<=0)    {        printf("The SeqList is empty\n");        return;    }    int i=0,j=0,flag=0;//用flag做一个标记,如果数组本来就是升序排列,则不用进行冒泡排序    for(i=0;i<seq->size-1;i++)    {        for(j=0;j<seq->size-1-i;j++)        {            if(seq->array[j]>seq->array[j+1])            {                Swap(&(seq->array[j]),&(seq->array[j+1]));                flag = 1;            }        }        if(!flag)            return;    }}void Swap(int*a,int*b){    int c;    c = *a;    *a = *b;    *b = c;}测试代码:int main(){    SeqList s;     InitSeqList(&s);     PushBack(&s,7);     PushBack(&s,23);     PushBack(&s,12);     PushBack(&s,4);     PushBack(&s,33);     PushBack(&s,21);     PushBack(&s,2);     Print(&s);     BubbleSort(&s);     Print(&s);     return 0;}

结果:
这里写图片描述
处理过程:
这里写图片描述
(2)选择排序

选择排序(Selection sort)是一种不稳定的排序方法,每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

void SelectSort(SeqList* seq)//选择排序{    assert(seq);    if(seq->size<=0)    {        printf("The SeqList is empty\n");        return;    }    int i=0,j=0;    for(i=0;i<seq->size-1;i++)    {        for(j=i+1;j<seq->size;j++)        {            if(seq->array[i]>seq->array[j])            {                Swap(&(seq->array[i]),&(seq->array[j]));            }        }    }}   

处理过程:
这里写图片描述
(3)插入排序

插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。

void InsertSort(SeqList* seq){    assert(seq);    if(seq->size<=0)    {        printf("The SeqList is empty\n");        return;    }    for(size_t i=0;i<seq->size-1;i++)    {        int end = i;        int tmp = seq->array[end+1];        while(end>=0&&seq->array[end]>tmp)        {            seq->array[end+1] =seq->array[end];            end--;        }        seq->array[end+1] = tmp;    }}

处理过程:
这里写图片描述
(3)二分查找

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
步骤:首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功。

int BinarySearch(SeqList* seq, DataType x)//二分查找,返回下标{    int left = 0;    int right = seq->size-1;    int mid = left+ ((right-left)>>1);    while(left<=right)    {        if(seq->array[mid]==x)        {            return mid;        }        else if(seq->array[mid]>x)        {            right = mid-1;            return left+ ((right-left)>>1);        }        else        {            left = mid+1;            return left+ ((right-left)>>1);        }    }    return -1;}测试代码:int main(){     SeqList s;     InitSeqList(&s);     PushBack(&s,1);     PushBack(&s,3);     PushBack(&s,4);     PushBack(&s,5);     PushBack(&s,7);     PushBack(&s,8);     PushBack(&s,9);     Print(&s);     printf("%d\n",BinarySearch(&s,8));     return 0;}

结果:
这里写图片描述
处理过程:
这里写图片描述

原创粉丝点击