最近整理的一些数据操作函数
#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--;//有效元素减1
count=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;
}
#endif
void 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后可能溢出从头开始了,因此先加SIZE
delindex = (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 0
void 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