1 汉诺塔问题

2 约瑟夫环

3 求“斐波纳契数列:1,1,2,3,5,8,13,21..."函数:递归与非递归

4 判断一个数是否是 2的幂次数:

5 计算一个整数的二进制数的 1的个数num

6 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。 ----像这种要求时间复杂度的 常常需要交换的算法


===========================================================================================

1 汉诺塔问题


//第一,把X上的n-1个盘通过Z移动到Y。

第二,把X上的最下面的盘移到Z。
//第三,因为n-1个盘全在Y上了,所以把Y当做X重复以上步骤就好了。递归中会保存数据


void moveNext( char pre, char next )
{
    cout<<pre<<"-->"<<next<<endl;
}
void hanio(int n,char XBlock,char YBlock,char ZBlock)
{
    if(n==1)
    {
        moveNext(XBlock,ZBlock);
    }
    else
    {
        hanio(n-1,XBlock,ZBlock,YBlock);
        moveNext(XBlock,ZBlock);
        hanio(n-1,YBlock,XBlock,ZBlock);
    }
}


2 约瑟夫环

首先建立一个 首尾相连的循环链表,for循环定义计算器,到达m改变链表的连接关系。

直到 最后剩下一个结点,pre=purnode。



typedef struct node 
{
    int num;
    struct node *next;
}LinkNode;
LinkNode * create_link( int num )
{
    LinkNode *p,*current,*head;   // p用来循环,current用来记录当前的位置。head(第一个数)用来返回一个链表
    p=(LinkNode*)malloc(sizeof(LinkNode));
    p->num=1;
    p->next=NULL;
    head=p;
    current=p;
    for(int i=2;i<=num;i++)
    {
        //生成新的结点---建立连接----转移到下一个
        p=(LinkNode*)malloc(sizeof(LinkNode));
        p->num=i;
        p->next=NULL;
        current->next=p;
        current=p;
    }
    current->next=head;     //链表的rail指向head,构成循环(循环列表list)。
    return head;
}
void make_play( LinkNode *link,int mcode )
{
    assert(link!=NULL&&mcode!=0);
    LinkNode *pLink=link,*pPre=NULL;   //错误:要给pre赋值才能使用。
    LinkNode *pDelte;                  //删除节点---free(标记结点)
    cout<<"亲,游戏开始了!"<<endl;
    while(pLink!=pPre)           //最后只留一个元素。
    {
        for(int n=1;n<mcode;n++)
        {
            pPre=pLink;
            pLink=pLink->next;
        }
        pDelte=pLink;
        cout<<"出列的是"<<pDelte->num<<endl;
        pPre->next=pLink->next;
        pLink=pPre->next;
        free(pDelte);
    }
    cout<<"最后出列的是:"<<pLink->num<<endl;
}


3 求“斐波纳契数列:1,1,2,3,5,8,13,21..."函数:递归与非递归

主要就是 初始化(退出条件)和循环条件转移(递归关系)的一个转换的关系。


int fib( int n )
{
    /*if(n==1||n==2)
    {
    return 1;
    }
    else
    {
    return fib(n-1)+fib(n-2);
    }*/
    if(n<=2)
    {
        return 1;
    }
    int valN1,valN2,sumN;         //是不是可以写成static形式的
    valN1=1;
    valN2=1;
    //sum ,n1,n2往后移动位置
    for(int i=1;i<=n-2;i++)      //计算的次数
    {
        sumN=valN1+valN2;
        valN2=valN1;
        valN1=sumN;
    }
    return sumN;
}



4 判断一个数是否是 2的幂次数:0==(a[i]&(a[i]-1)

int find2power( int a[] ,int len)
{
    int count=0;
    for(int i=0;i<len;i++)
    {
        if(0==(a[i]&(a[i]-1)))
        {
            count++;
        }
    }
    cout<<count<<endl;
    return count;
}


5 计算一个整数的二进制数的 1的个数num

统计一个整数的二进制数的 1的个数: num&1(一次统计最右边的那个数值是否是1)

int num1OfBinery( int num )
{
    int count=0;
    while(num)
    {
        if(num&1)
        {
            count++;
        }
        num>>=1;   //向右移动,除以2
    }
    return count;
}


6 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。

----像这种要求时间复杂度O(n)的 常常需要交换的算法:添加一个计算当前遇到的奇数个元素的mark标记(标志下一个遇到的奇数应该插入的位置),遇到奇数的话---swap(i,mark)


void swapElement( int arr[], int i, int mark )
{
    int tmp;
    tmp=arr[i];
    arr[i]=arr[mark];
    arr[mark]=tmp;
}
void printArrray( int arr[], int num )
{
    cout<<"输出的数组是:"<<endl;
    for(int i=0;i<num;i++)
    {
        cout<<arr[i]<<endl;
    }
}
// 两个变量:一个i遍历数组,另一个标记需要的位置( 有几个奇数符合条件的,排在前几位)
//1 找到第一个,判断移动  2 循环
void partition( int arr[],int num )
{
    int i=0,mark=0;
    while(i<num&&(arr[i]&1==0))  //找到第一个奇数:= while +if(break)
    {
        i++;
    }
    if(i==num)                //全是偶数
        return;
    swapElement(arr,i,mark);
    i++;
    mark++;
    while(i<num)
    {
        if((arr[i]&1)==1)
        {
            swapElement(arr,i,mark);
            mark++;
            printArrray(arr,num);
        }
        i++;
    }
    printArrray(arr,num);
}

===========================================================================


测试的代码:

/*
    int n;
    printf("请输入要移动的块数:");
    scanf("%d",&n);
    hanio(n,'X','Y','Z');*/
    int num=7;
    //cout<<fib(num)<<endl;
    LinkNode *head=create_link(num);
    make_play(head,5);
    int arr[]={1,2,3,4,5,6,7,8,16,50};
    int len=sizeof(arr)/sizeof(int);
    find2power(arr,len);
    /*int num=7;
    cout<<num1OfBinery(num)<<endl;*/
    /*int arr[]={1,2,4,6,7,5,8,9};
    int n=sizeof(arr)/sizeof(int);
    partition(arr,n);*/