C语言间隔删除数组的探究

来源:互联网 发布:什么是数据库架构师 编辑:程序博客网 时间:2024/05/22 09:44

最近整理的一些数据操作函数

#include <stdlib.h>#include <stdio.h>#define SIZE2 1000#define STEP 2#define DELFLAG (SIZE2 + 1)#define MaxCount 1000#define null 0#define   FST_ROUND_LEFT   (MaxCount - MaxCount/(STEP+1))#define   ARRAYSIZE (MaxCount+FST_ROUND_LEFT)// 在第一轮里未删除的数,应该保存未删除数据的下标// 以后待删除的数已经都是下标了,应该保存其值,最后删除的数就是其原始数的下标了typedef struct _node{int data;int index;struct _node *next;}node,pNode;const int size = 1000;void test1(void);void test2(void);void test3(void);void test4(void);void test5(void);void test6(void);void test7(void);void test8(void);void test9(void);void test9(void){    printf("this is hello world\n");}int main(void){    test1();    test2();    test3();    test4();    test5();    test6();    test7();    test8();    test9();    return 0;}void test1(void){    int arr[size];    int currentSize = size; //指示当前数组还剩于的数组个数,如果为1删除完毕    int count = 0; //计数用;    int k = 0;    //赋值1000个    for(;k<size;k++)    {arr[k] = k;    }    //i用%循环计数,终止条件是删除的只剩下一个数    int i = 0;    for(;(i<size)&&(currentSize!=1);i = (i+1)%size)    {if(arr[i]!=-1)//-1表示已经删除的标志,未删除则计数,已删除则循环下一位{    //按照计数间隔计数,达到间隔时删除数据    if(count>=0 && count < 2 )    {count++;    }    else if(count ==2)//间隔为二    {arr[i] = -1; //元素做上标记表示已删除currentSize--;//有效元素减1count=0;//并将计数值归零;    }}    }    int j = 0;    for(;j < size;j++)//显示最后结果    {if(arr[j]!= -1){    printf("test1结果是: %d \n",j);    break;}    }}#if 0#include <iostream> using namespace std;    struct Node  {      int value;      bool isDeleted;  };  int main()  {          Node a[1001];          int i,n = 1000;          for (i = 0; i < n; ++i)          {          a[i].value = i;          a[i].isDeleted = false;                    }      int cur = 0,count,num = n;      while (num != 1)      {              count = 0;              while (count != 2)              {              cur = (cur+1)%n;              if (a[cur].isDeleted == false)              {                      count++;              }              }              a[cur].isDeleted = true;             // cout<<a[cur].value<<"  ";              while (a[cur].isDeleted != false)              {              cur = (cur+1)%n;              }          --num;      }      cout<<endl;      cout << cur << endl;      system("pause");      return 0;  }#endifvoid test2(void){        int arr[SIZE2];int currentSize = SIZE2;//为1时表示删除完毕int count = 0;int i = 0;int lastindex = 0;int lastvalue = 0;int k = 0;for(;k<SIZE2;k++){    arr[k] = k;}while(currentSize != 0){    if(arr[i] != DELFLAG)    {if(count++ == STEP){    lastindex = i;    lastvalue = arr[i];    arr[i] = DELFLAG;    currentSize--;    count = 0;}    }    i = (i+1)%SIZE2; }printf("test2最后删除的数的原始坐标: %d \n",lastindex);//printf("最后删除的数是 : %d\n",lastvalue);}void test3(void){    int arr[SIZE2];    int i = 0;    for(;i < SIZE2;i++)    {arr[i] = i;    }    int j = 0;    int count = 0;    while(count < SIZE2 - 1)//999保留最后一个为删除的数    {while(arr[j%1000] == DELFLAG){    j = (++j)%SIZE2;}j = (++j)%SIZE2;//第一个未访问的数while(arr[j%1000]== DELFLAG){    j = (++j)%1000;}j = (++j)%1000;   //第二个未访问的数while(arr[j%1000]== DELFLAG){    j = (++j)%1000;}arr[j] = DELFLAG; // 删除第三个数++count;    }    while(arr[j]==DELFLAG) // 扫描最后一个未删除的数    j = (++j)%1000;    printf("test3最后的数的下标 : %d\n",j);}void test4(void){    int arr[SIZE2];    int i =0;    for(;i <SIZE2;i++)    {arr[i] = i;    }    int j = 0;    int count = 0;    int stepcounter = 0;    int delindex = 0;    while(count < SIZE2)  //删除总次数    {//删除一个while(stepcounter<=STEP)//寻找第三个未访问的数{while(arr[j%SIZE2] == DELFLAG)//剔除已删除的j = (++j)%SIZE2;j = (++j)%SIZE2;//(++j)中的j为一个未访问的的数,而非保存后的j,故下面delindex = j - 1;stepcounter++;}//delindex = j - 1;//由于上面j加1后可能溢出从头开始了,因此先加SIZEdelindex = (j + SIZE2 - 1)%SIZE2;//保存当前删除数的下标stepcounter = 0;arr[delindex] = DELFLAG; //删除第三个未访问的数++count;    }    printf("test4下标是:%d\n",delindex);}void test5(void){    int arr[SIZE2];    int currentSize = SIZE2;    int count = 0;    int lastdel = 0;    int i = 0;    int k = 0;    for(;k<SIZE2;k++)    {//arr[k] = SIZE2 - k;arr[k] = k;    }        while(currentSize != 0)    {if(arr[i] >= 0)//当前数大于等于0,未删除,删除的话则看下一个{    //按照计数间隔来计数,达到计数间隔删除数据    if(count++ == STEP)    {lastdel = i;arr[i] = -1;//将此数的最高位置1,此时其为负数,表示删除//arr[i] = DELFLAG;currentSize--; //有效元素减1;count = 0;//计数值归零    }}i = (i + 1)%SIZE2;    }    printf("test5下标是:  %d\n",lastdel);//    printf("最后的删除的数:  %d\n",i);    //清除最高位的1,恢复原始数组    for(k = 0;k < SIZE2;k++)    {arr[k] &= ~DELFLAG; // 注意这种清除方式的移植性高到爆     }}void test6(void){    int   list[2*MaxCount];                               //多分配一倍的空间,用来放循环数据      int   i,index=0,tail,delcount=0;         for(i=0;i<MaxCount;i++)      {   list[i]=i;     //初始化,存放0~999     }         tail=MaxCount; //list[tail]用来存放不删除的数据     while(delcount<MaxCount) //删除1000个就退出     {   //第三个数据删除,此处有误,因为index循环时重新赋值了,导致((index %3)的错误 if((index %3)==2){      delcount++;      //       printf("%d\t",list[index]);  }  else       //前两个数据放到队列末尾,  {      list[tail]=list[index];      tail=(tail+1) % (2*MaxCount);           }   index=(index+1) % (2*MaxCount);//步近    }   printf("test6下标是:%d\n",index);   return;    // 缺点,不能输出最后一个删除数的原始下标,只能输出其值,因为该数组可能是随机的,下标与值可能不一致  // 此题的考点就在于删除过程中拷贝了数据后如何保存原始位置,否则的话我每次删除一个值后,将后面所有的数前移,然后再删,没有意义了}void test7(void){int   list[2*MaxCount]; //多分配一倍的空间,用来放循环数据  int   i,index=0,counter=0,tail,delcount=0; int    lastdel = 0;  for(i=0;i<MaxCount;i++)   list[i]=i;     //初始化,存放0~999      tail=MaxCount; //list[tail]用来存放不删除的数据        while(delcount<MaxCount) //删除1000个就退出     {     counter++;   if(counter==3) //第三个数据删除,单独计数,不用index     {     delcount++;   counter = 0;   lastdel = list[index];    //printf("%d\t",list[index]);     }     else       //前两个数据放到队列末尾,     {     list[tail]=list[index];     tail=(tail+1)%(2*MaxCount);     }     index=(index+1)%(2*MaxCount);//步近     }          printf("test7结果哦是:%d\n",lastdel);}void test8(void){    int   list[ARRAYSIZE];      //多分配一倍的空间,用来放循环数据,其实多分配\\FST_ROUND_LEFT即可了,即 list[FST_ROUND_LEFT+MaxCount],后面的循环值要改下     int   i,index=0,counter=0,tail,delcount=0;     int           lastdel = 0, firstround = 1;    for(i=0;i<MaxCount;i++)      list[i]=MaxCount - 1 - i;     //初始化,存放999~0,此时下标和数是非对应的      tail=MaxCount; //list[tail]用来存放不删除的数据下标或已经保存的下标      while(delcount<MaxCount) //删除1000个就退出      {          counter++;       if(counter==3) //第三个数据删除         {             delcount++;           counter = 0;           if(firstround)           lastdel=index;           else           lastdel=list[index];           //printf("%d\t",list[index]);         }         else       //前两个数据放到队列末尾,        {           if(firstround)           list[tail]=index;           else           list[tail]=list[index];           if(firstround)           if(tail - MaxCount == FST_ROUND_LEFT - 1)            {               firstround = 0;       // 清除第一轮标志,以后保存值(保存后的下标)//               printf("%d\n",FST_ROUND_LEFT);           }   tail=(tail+1)%(ARRAYSIZE);  }      index=(index+1)%(ARRAYSIZE);//步近      }      printf("test8结果的是:%d\n",lastdel);}#if 0void test9(void){    int arr[SIZE2];    int i = 0;    for (;i<SIZE2;++i)    {arr[i]=SIZE2-i; // 实际情况可能是随机    }    pNode head=(pNode)malloc(sizeof(node));    head->data=arr[0];    head->index=0;    head->next=null;    pNode p=head;    for(i=1;i<1000;i++)    {pNode tmp=(pNode)malloc(sizeof(node));tmp->data=arr[i]; tmp->index=i;tmp->next=null;head->next=tmp;head=head->next;    }    head->next=p;    while(p!=p->next) // p指向自己时,循环链表只剩一个元素了    {p->next->next=p->next->next->next;p=p->next->next;    }    // 存在内存泄漏     printf("test9结果是: %d\n",p->data);    //cout<<p->index<< ' '<< p->data<<endl;}#endif


0 0
原创粉丝点击