#include <stdio.h>
#include <assert.h>
#include <string.h>
//顺序表的静态存储
#define MAXSIZE 5
typedef int DataType;
typedef struct SeqList
{
 DataType array[MAXSIZE]; //数组大小
 size_t size;             //有效元素个数
}SeqList;
void InitSeqList(SeqList *Pseq);
void PushBack(SeqList *Pseq, DataType x);
void PushFront(SeqList *Pseq, DataType x);
void PopBack(SeqList *Pseq);
void PopFront(SeqList *Pseq);
void PrintSeqList(SeqList *Pseq);
void InsertSeqList(SeqList *Pseq, size_t pos, DataType x);
int Find(SeqList *Pseq, DataType x); //按值查找元素位置
void Erase(SeqList *Pseq, size_t pos);//将查找到的元素删除
void Remove(SeqList *Pseq, DataType x);
void Remove2(SeqList *Pseq, DataType x);//不复用Find和Erase
void RemoveAll(SeqList *Pseq, DataType x);
void RemoveAll2(SeqList *Pseq, DataType x);//不复用Find和Erase,利用count标记,效率更高
void BubbleSort(SeqList *Pseq);            //冒泡排序
void BubbleSort1(SeqList *Pseq);            //冒泡排序优化1
void BubbleSort2(SeqList *Pseq);            //冒泡排序优化2
void SelectSort(SeqList *Pseq);            //选择排序
void SelectSort1(SeqList *Pseq);            //选择排序优化
int BinarySearch1(SeqList *Pseq, DataType x);  //二分查找
int BinarySearch2(SeqList *Pseq, DataType x);  //二分查找 边界讨论
void InitSeqList(SeqList *Pseq)
{
 memset(Pseq->array, 0, sizeof(DataType)*MAXSIZE);
 Pseq->size = 0;
}
//1.检查参数
//2.边界条件的检查
//3.完成功能逻辑
void PushBack(SeqList *Pseq, DataType x)     //判断表是否已满
{
 assert(Pseq);
 if (Pseq->size >= MAXSIZE)
 {
  printf("SeqList is full");
  return;
 }
 else
 {
  Pseq->array[Pseq->size] = x;
  Pseq->size++;
 }
 
}
void PopBack(SeqList *Pseq)    //判断表是否为空
{
 assert(Pseq);
 if (Pseq->size<= 0)
 {
  printf("SeqList is empty");
  return;
 }
 //Pseq->array[Pseq->size-1] = 0;
 Pseq->size--;
}
void PrintSeqList(SeqList *Pseq)
{
 assert(Pseq);
 int i = 0;
 for (i = 0; i < Pseq->size; i++)
 {
  printf("%d ", Pseq->array[i]);
 
 }
 printf("\n");
}
void PushFront(SeqList *Pseq, DataType x)
{
 int begin = Pseq->size - 1;       //学会写标识
 assert(Pseq);
 if (Pseq->size >= MAXSIZE)
 {
  printf("SeqList is full");
  return;
 }
 
 for (; begin >= 0; --begin)
 {
  Pseq->array[begin + 1] = Pseq->array[begin];
 }
 Pseq->array[0] = x;
 Pseq->size++;
}
void PopFront(SeqList *Pseq)
{
 assert(Pseq);
 int begin = 1;
 if (Pseq->size <= 0)
 {
  printf("SeqList is empty");
  return;
 }
 for (begin = 1; begin <= Pseq->size-1; ++begin)
 {
  Pseq->array[begin-1 ] = Pseq->array[begin];
 }
 Pseq->size--;
}
void InsertSeqList(SeqList *Pseq, size_t pos, DataType x)
{
 assert(Pseq);
 assert(pos <= Pseq->size);
 if (Pseq->size >= MAXSIZE)
 {
  printf("SeqList is full");
  return;
 }
 int begin = Pseq->size - 1;
 for (begin = Pseq->size - 1; begin >= pos; begin--)
 {
  Pseq->array[begin + 1] = Pseq->array[begin];
 }
 Pseq->array[pos] = x;
 Pseq->size++;
}
int Find(SeqList *Pseq, DataType x)
{
 assert(Pseq);
 int i = 0;
 for (i = 0; i <= Pseq->size - 1; i++)
 {
  if (Pseq->array[i] == x)
   return i+1;
 }
 return -1;
}
void Erase(SeqList *Pseq, size_t pos)
{
 assert(Pseq);
 assert(pos < Pseq->size);
 int begin = pos ;
 for (begin = pos ; begin <= Pseq->size ; ++begin)
 {
  Pseq->array[begin -1] = Pseq->array[begin];
 }
 Pseq->size--;
}
//复用Find和Erase
void Remove(SeqList *Pseq, DataType x)
{
 assert(Pseq);
 int pos;
 pos = Find(Pseq, x);
 if (pos != -1)
 {
  Erase(Pseq, pos);
 }
}
//不复用Find和Erase
void Remove2(SeqList *Pseq,DataType x)
{
 assert(Pseq);
 size_t i = 0;
 size_t j = 0;
 for (i = 0; i < Pseq->size ; ++i)
 {
  if (Pseq->array[i] == x)
  {
   for (j = i; j < Pseq->size-1; ++j)
   {
    Pseq->array[j] = Pseq->array[j + 1];
   }
   Pseq->size--;
  }
 }
}
//复用Find和Erase
void RemoveAll(SeqList *Pseq, DataType x)
{
 assert(Pseq);
 int pos=0;
 pos = Find(Pseq, x);
 while (pos != -1)
 {
  Erase(Pseq, pos);
  pos = Find(Pseq, x);
 }
}
//不复用Find和Erase
void RemoveAll2(SeqList *Pseq, DataType x)
{
 assert(Pseq);
 size_t i = 0;
 size_t count = 0;
 for (i = 0; i < Pseq->size; ++i)
 {
  if (Pseq->array[i] == x)       //只要遇到相同的x,count++,其后面的数向前移动count,将其覆盖掉。
  {
   count++;
  }
  else
  {
   Pseq->array[i - count] = Pseq->array[i];
  }
 }
 Pseq->size = Pseq->size - count;
}
void BubbleSort(SeqList *Pseq)            //冒泡排序
{
 size_t i = 0;
 size_t j = 0;
 assert(Pseq);
 for (i = 0; i < Pseq->size; ++i)
 {
  for (j =0; j < Pseq->size - i; ++j)
  {
   if (Pseq->array[j]>Pseq->array[j+1])
   {
    DataType tmp = Pseq->array[j];
    Pseq->array[j] = Pseq->array[j+1];
     Pseq->array[j+1] = tmp;
   }
  }
 }
 
}
//冒泡排序优化1:设置一个标志,如果这一趟发生了交换,则为true,否则为false.
//明显如果有一趟没有发生交换,说明排序已经完成。
void BubbleSort2(SeqList *Pseq)                 //冒泡排序优化1,利用一个标识减少排序次数
{
 size_t i = 0;
 size_t j = 0;
 bool flag = true;
 size_t length = Pseq->size;
 assert(Pseq);
 while (flag)
 {
  flag = false;
  for (j = 0; j < length-1&&length>0; ++j)
  {
   if (Pseq->array[j] > Pseq->array[j + 1])
   {
    DataType tmp = Pseq->array[j];
    Pseq->array[j] = Pseq->array[j + 1];
    Pseq->array[j + 1] = tmp;
    flag = true;
   }
  }
  length--;
 }
}
//冒泡排序优化2:如果有100个数的数组,仅前面10个无序,后面90个都已排好序,
//且都大于前面10个数字,那么在第一趟遍历后,最后发生交换的位置必定小于10,
//且这个位置之后的数据都已有序,记录下这个位置,第二次只要从数组头部遍历到这个位置即可。
void BubbleSort3(SeqList *Pseq)                 //冒泡排序优化2,记录第一次遍历的最后交换位置
{
 size_t k = 0;
 size_t j = 0;
 size_t flag = Pseq->size;
 assert(Pseq);
 
 while (flag)
 {
  k=flag;
  flag = 0;
  for (j = 0; j < k; ++j)
  {
   if (Pseq->array[j] > Pseq->array[j + 1])
   {
    DataType tmp = Pseq->array[j];
    Pseq->array[j] = Pseq->array[j + 1];
    Pseq->array[j + 1] = tmp;
    flag =j;
   }
  }
 }
}
void SelectSort(SeqList *Pseq)            //选择排序
{
 size_t i = 0,j=0;
 size_t min = 0;
 for (i = 0; i < Pseq->size-1 ; i++)
 {
  min = i;
  for (j = i + 1; j < Pseq->size; j++)
  {
   if (Pseq->array[min] > Pseq->array[j])
   {
    min = j;
   }
  }
  if (min != i)
  {
   DataType tmp = Pseq->array[min];
   Pseq->array[min] = Pseq->array[i];
   Pseq->array[i] = tmp;
  }
 }
}

void SelectSort2(SeqList *Pseq)            //选择排序优化,一次选出最大最小排在序列两端
{
 size_t i = 0, j = 0;
 size_t min = 0, max = 0;
 size_t left = 0, right = 0;
 for (left = 0, right = Pseq->size - 1; left <= right; left++, right--)
 {
  min = left;
  max = right;
  for (i = left; i < right; ++i)
  {
   if (Pseq->array[i] < Pseq->array[min])
   {
    min = i;
   }
   if (Pseq->array[i]>Pseq->array[max])
   {
    max = i;
   }
  }
  if (min != left)
  {
   DataType tmp = Pseq->array[min];
   Pseq->array[min] = Pseq->array[left];
   Pseq->array[left] = tmp;
  }
  if (max == left)
  {
   max = min;
  }
  if (max != right)
  {
   DataType tmp = Pseq->array[max];
   Pseq->array[max] = Pseq->array[right];
   Pseq->array[right] = tmp;
  }
 }
}
int BinarySearch1(SeqList *Pseq, DataType x)   //二分查找,二分查找的边界讨论  左闭右闭<=,right=mid-1
{
 int left = 0;
 int right = Pseq->size-1;
 while (left <=right)
 {
  int mid = left + (right - left) / 2;
  if (Pseq->array[mid] > x)
  {
   right = mid-1;
  }
  if (Pseq->array[mid] < x)
  {
   left = mid + 1;
  }
  if (Pseq->array[mid] == x)
  {
   return mid;
  }
 }
 return -1;
}

int BinarySearch2(SeqList *Pseq, DataType x)   //二分查找,二分查找的边界讨论   左开右开,right=mid
{
 int left = 0;
 int right = Pseq->size ;
 while (left < right)
 {
  int mid = left + (right - left) / 2;
  if (Pseq->array[mid] > x)
  {
   right = mid ;
  }
  if (Pseq->array[mid] < x)
  {
   left = mid + 1;
  }
  if (Pseq->array[mid] == x)
  {
   return mid;
  }
 }
 return -1;
}