几个数据结构的程序

来源:互联网 发布:mysql查看表空间大小 编辑:程序博客网 时间:2024/06/05 18:08

典型的约瑟夫环问题。

原问题比你的问题要复杂一点。

我以前写的程序:
1.
用数组。

# include "stdio.h"
# define SIZE 100
main()
{
    int m,n,i;
    int array[SIZE];
    printf("
约瑟夫环求解,当前设置最大人数为%d./n",SIZE);
    printf("
报数上限:/n");
    scanf("%d",&m);
    printf("
总人数为:/n");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
    printf("
%d人的密码为:",i+1);
    scanf("%d",&array[i]);
    }
    joseph(array,m,n);
}
int joseph(a,m,n)
int a[],m,n;
{
    int b[SIZE];        /*
计录编号数组.*/
    int i;                /*
计数器.*/
    int flag=0;
    int code;            /*
删取人的号码.*/
    int sum=n;            /*
现存人数.*/
    int point=0;        /*
当前报数人的位置.*/
    int num=m;
    for(i=0;i<n;i++)    /*
计录数组.*/
    {
    b[i]=i+1;
    }
    while(sum!=0)        /*
当人数不为零时继续循环.*/
    {
    for(i=1;i<=num;i++)    /*
进行报数.*/
    {

        if(point>=sum)    /*
当前报数位置超过最后一人时从第一人报起.*/
        {point=1;}
        else point++;

    }
    num=a[point-1];    /*
取密码.*/
    code=b[point-1];    /*
取号码.*/
    for(i=point;i<=sum;i++) /*
删去退出的人.*/
    {
        a[i-1]=a[i];
        b[i-1]=b[i];

    }
    sum--;            /*
现存总人数.*/
    flag++;            /*
退出的人数.*/
    point--;
    printf("
已退出%d,退出的人的编号为%d./n",flag,code);
    }

}

2.
用循环链表

# include "stdio.h"
# include "alloc.h"
# define LEN sizeof(struct player)
    struct player
    {
    int num;    /*
编号*/
    int secret;    /*
密码*/
    struct player *next;
    };
    int n;    /*
总人数*/
main()
{
    int m;
    void create();
    void delete();
    struct player *head;
    head=(struct player *)malloc(LEN);
    printf("
请输入第一次的密码:/n");
    scanf("%d",&m);
    create(head);
    delete(head,m);

}
void create(struct player *head)
{
    struct player *p1,*p2,*p;
    p1=p2=head;
    printf("
请输入编号,密码,当编号为零时输入结束./n");
    printf("
总人数为:/n");
    scanf("%d",&n);
    do
    {
    p=p2;
    p2=p1;
    printf("
编号:");
    scanf("%d",&p2->num);
    printf("
密码:");
    scanf("%d",&p2->secret);
    p1=(struct player *)malloc(LEN);
    p2->next=p1;
    }while(p2->num!=0);
    p->next=head;
    free(p1);
}
void delete(struct player *head,int m)
{
    int i;
    struct player *p,*q;
    int sum;
    p=head;
    sum=m;
    while(n!=0)
    {
    for(i=1;i<sum;i++)
    { q=p;
        p=p->next;
    }
    printf("%d,",p->num);
    sum=p->secret;
    q->next=p->next;
    p=p->next;
    n=n-1;
    }
}

题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从13报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。


1.
程序分析:
2.
程序源代码:
#define nmax 50
main()
{
int i,k,m,n,num[nmax],*p;
printf("please input the total of numbers:");
scanf("%d",&n);
p=num;
for(i=0;i<n;i++)
 *(p+i)=i+1;
 
i=0;
 
k=0;
 
m=0;
 
while(m<n-1)
 
{
 
if(*(p+i)!=0) k++;
 
if(k==3)
 
{ *(p+i)=0;
 
k=0;
 
m++;
 }
i++;
if(i==n) i=0;
}
while(*p==0) p++;
printf("%d is left/n",*p);
}

我写了一个带头结点的单链表逆置程序,程序的执行结果没什么问题,只是要高手指点一下我写的代码有没有哪里不规范的地方?  
   
  /****************************************************************  
  *    
文件名:nz.c       nz就是逆置!)  
  *    
文件描述:带头结点的单链表逆置  
  *    
创建人:沁园枫  
  *    
创建时间:200622  
  ****************************************************************/  
  #include   "stdio.h"  
  typedef int ElemType
  typedef   struct   node       /*
单链表结点*/  
  {  
    ElemType    data;                       /*
数据域*/  
    struct   node   *next;       /*
指针域*/  
  }slink;  
   
  void   main()                     /*
主函数*/  
  {  
   slink   *creatslink();                 /*
声明xjlb(新建链表)函数*/  
   slink   *inverse(slink  *);       /*
声明nzlb(逆置链表)函数*/  
   slink   *h,*p;  
    h= creatslink();                       /*
调用xjlb(新建链表)函数*/  
    p=h;  
    while(p-> next!=NULL)/*
输出新建单链表后的各元素*/  
    {  
      printf("%d",p-> next ->data);  
      p=p-> next;  
    }  
    printf("/n");  
    h= inverse(h);                     /*
调用nzlb(逆置链表)函数*/  
    while(h-> next!=NULL)/*
输出逆置后的单链表各元素*/  
    {  
      printf("%d",h-> next ->data);  
      h=h-> next;  
    }  
    getch();                         /*
调用getch函数,不知道什么意思的自己查查!*/  
  }  
   
 slink   * creatslink()                     /*
新建链表函数*/  
  {  
    slink   *h,*l,*a;  
    int   i;  
    h=( slink   *)malloc(sizeof(slink));   /*
创建头结点*/
    h-> next =NULL;  
    a=h;  
    for(i=0;i<5;i++)  
    {  
      l=( slink   *)malloc(sizeof(slink));  
      l->data=i;  
      a-> next =l;  
      a=a-> next;  
    }  
    a-> next =NULL;  
    return   h;  
  }  
   
 slink   * inverse (slink   *h)         /*
逆置链表函数*/  
  {  
   slink   *p,*q;  
    p=h-> next;  
    h-> next =NULL;  
    while(p!=NULL)  
    {  
      q=p;  
      p=p-> next;  
      q-> next =h-> next;  
      h-> next =q;  
    }  
    return   h;  
  }  

 

单链表逆置算法

单链表逆置算法

struct node
 {
  int num;
  struct node *next;
 }
 struct node* reverse(struct node *head)
 //head 链表头结点
 {
  struct node *p,*temp1,*temp2;
  if(head==NULL________) return head; //||head->next==NULL
  p=head->next;head->next=NULL;
  while(________) //p!=NULLp
  {
   temp1=head;
   ________; //head=p;
   temp2=p;
   p=p->next;
   ________; //temp2->next=temp1;head->next=temp1;
   }//Match while statenment
   return head; //返回逆置后的链表的头结点
 }

 

struct node
 {
  int num;
  struct node *next;
 }
 struct node* reverse(struct node *head)
 //head 链表头结点
 {
  struct node *p,*temp1,*temp2;
  if(head==NULL||head->next==NULL) return head;             

p=head->next;head->next=NULL;
  while(p!=NULLp)

{
   temp1=head;
   head=p;
   temp2=p;
   p=p->next;
   temp2->next=temp1;head->next=temp1;
   }//Match while statenment
   return head; //返回逆置后的链表的头结点
 }

 

最大子列和 n的阶乘中有多少个0 10进制to2进制 单链表逆置 判断链表中是否有环 文件中有多少行

#ifndef MYLIST_H
#define MYLIST_H

#include <string>

struct listnode
{
 int value;
 listnode *next;

 listnode ( int num ): value (num), next (NULL)
 {
 }
};
class Mylist
{
public:

 Mylist ();
 ~Mylist ();
 void Insert ( int value ) ;
 std::string GetEntireList ();

 void Reverse ();

private:
 listnode *head;

};
#endif

//----------------------------------------------------------------


#include "Mylist.h"

using namespace std;

Mylist::Mylist ()
{
 head = NULL;
}

Mylist::~Mylist()
{
 if ( head != NULL )
 {
  listnode *temp = head ;
  while ( head != NULL )
  {
   temp = head->next;
   delete head;
   head = temp;
  }
 }
}

void Mylist::Insert ( int value )
{
 if ( head == NULL )
 {
  head = new listnode ( 0 );
 }

 listnode *curnode = new listnode ( value );

 listnode *temp = head;
 while (  temp->next != NULL )
 {
  temp = temp->next;
 }

 temp->next = curnode;
}

string Mylist::GetEntireList ()
{
 string str = "";

 listnode *temp = head->next ;
 while ( temp != NULL )
 {
  str += temp->value + '0'   ;
  str += ' ' ;
  temp = temp->next;
 }

 return str;
}

void Mylist::Reverse ()
{
 if ( head == NULL || head->next == NULL )
 {
  return;
 }

 listnode *end = head;
 while ( end->next != NULL )
 {
  end = end->next;
 }
 
 listnode *curnode = head->next;

 while ( curnode != end )
 {
  //
curnode从链表中删除
  head->next = curnode->next;

  //curnode插入到end后面
  curnode->next = end->next;
  end->next = curnode;

  curnode = head->next;  
 }

}
 //
判断链表中是否存在着环
bool Mylist::HasaCycle ()
{
 listnode *itr1 = NULL;
 listnode *itr2 = NULL;

 // 如果链表为空则返回false
 if ( head == NULL || head != NULL && ( head->next == NULL )  )
 {
  return false;
 }

 itr1 = head->next;
 itr2 = itr1->next;
 if ( itr2 == NULL )
 {
  return false;
 }

 // 如果head-next指向了head ,或者itr1-head 指向了itr1,或者itr1-next指向了head,有环
 if ( itr1 == head || itr2 == itr1 || itr2 == head )
 {
  return true;
 }

 // head -> itr1 -> itr2 -> * 
 while ( itr1 != NULL && itr2 != NULL && itr2->next != NULL  )
 {
  if ( itr1 == itr2 || itr2->next == itr1 )
  {
   return true;
  }
  itr1 = itr1->next;
  itr2 = itr2->next->next;
 }
 
 return false;
}


}

//================================

// testcpp

#include <fstream>
#include <iostream>
#include <math.h>
#include <string>
#include <list>

#include "Mylist.h"

using namespace std;

//==================================================
//
获得datatxt文件中有多少行
int  GetTotalLineCount ()
{
 ifstream ifs;
 ifs.open ( "data.txt", ios::in );

 int count  = 1 ;

 //string p;

// while ( getline( ifs, p ) ) { ++count; }
 char ch;

 while ( ifs.get( ch ) )
 {
  if ( ch == '/n')
  {
   ++count;
  }
 }
 ifs.close();
 return count;
}
//================================================================
//
计算正整数num的阶乘中有多少个0
const int FIVE = 5;

// 得到不大于 num5的最大次方,如 num = 5 时返回 1 26 时返回 2
int LowerNearestPow ( int num )
{
 int powoffive = 1;

 while ( pow ( FIVE, powoffive ) <= num )
 {
  ++powoffive;
 }

 return powoffive;
}
//
考虑25125 625 等的情况
int GetZerosofXFactorial ( int num )
{
 int lowernearestpow = LowerNearestPow ( num );

 int zerocount = 0;
 while (  lowernearestpow > 0 )
 {
  zerocount += num / pow ( FIVE,  lowernearestpow ) ;
  --lowernearestpow;
 }
 
 return zerocount;
}
//=========================================================================
//
10进制正整数num转化为2进制数

const int TWO = 2 ;

string  DecimalToBin ( unsigned int num )
{
 if ( num == 0 )
 {
  return "0";
 }
 string binform = "";

 while ( num > 0 )
 {
  binform.insert ( binform.begin(),  num % TWO + '0' );
  num /= TWO ;
 }

 return binform;

}
//=========================================================================
//
求一个整数数组的最大子列和
int MaxSubArraySum ( int *array, int size )
{
 int sum = 0;

 while ( size >= 0 )
 {

  if ( array[size] > 0 )
  {
   sum += array[ size ];
  }

  else if ( array[size] < 0  )
  {
   if ( sum == 0 )   
   {
    sum = array[size];
   }
  }// end of else

  --size;

 }// end of while

 return sum;
}

//=========================================================================
void main ()
{
// int count = GetTotalLineCount ();
// cout << count << endl;

// while ( 1 )
// {
//  cout << "
请输入一个数,本程序将计算这个数的阶乘中有多少个0" << endl;
//  int num;
//  cin >> num ;

//  cout << GetZerosofXFactorial ( num ) << endl;
// }
 

// while ( 1 )
// {
//  cout << "
请输入一个正整数,本程序将计算这个数的二进制形式:" << endl;

//  unsigned int num;
//  cin >> num ;

//  cout << DecimalToBin ( num ) << endl;

// }
// Mylist intlist;
// for ( int i=0; i<8; ++i )
// {
//  intlist.Insert ( i );
// }
// string str = intlist.GetEntireList ();
// cout << "
在逆置之前链表内容为:" << str << endl;

// intlist.Reverse();

// str = intlist.GetEntireList ();
// cout << "
在逆置之后链表内容为:" << str << endl;

// int sum[] = { -1, -2, 0, -4, -6, -1}; // -1
 //{ 1, 2, -1, -4, 6, 1};   // 10
// int size = sizeof( sum ) / sizeof(int) - 1;
// cout << MaxSubArraySum ( sum , size ) << endl;
}

n个人围成一圈,顺序排号.从第一个人开始报数(1m报数),凡报到m的人退出圈子,问最后留下的是原来第几号?

链表:
#include<stdio.h>
#include<malloc.h>

typedef struct node{
int info;
struct node *next;
};

node *tbuildhlink(int n)  /*带头节点的尾插法*/
{
    node *head,*s,*p2;
    int i=1;
    
    head=(node *)malloc(sizeof(node));
    p2=head;
    while(i<=n)
    {
        s=(node *)malloc(sizeof(node));
        s->info=i;
        p2->next=s;
        p2=s;
        i++;
    }
    if(p2)  p2->next=head;
    return(head);
}

void Display(struct node* head)
{
    node *p;
    p=head->next;
    if(!p)
    {
        printf("/nthe hlink is empty!");
    }
    else
    {
        printf("/nthe value of the hlink is:/n");
        while(p!=head)
        {
            printf("%d--->",p->info);
            p=p->next;
        }
    }
    printf("^/n");
}
int delete_node(struct node *head,int  n,int m)
{
    int count=1,sum=n;
    struct node *p,*pre;
    pre=head;
    p=pre->next;
    while(sum>1)
    {
        if(p==head)
        {
            p=p->next;
        }            
        if(count<m)
        {
            pre=p;
            p=p->next;    
            count++;
        }
        if(count==m)
        {
            if(p==head)
            {
                p=p->next;
            }
            printf("
%d个人出列./n",p->info);
            pre->next=p->next;
            free(p);
            p=pre->next;
            count=1;
            sum--;
        }
    }
    return(pre->info);
}

    
int main()
{
    node *head;
    int n,m;
    
    printf("
输入n,m:");
    scanf("%d%d",&n,&m);
    head=tbuildhlink(n);
    Display(head);
    printf("
最后剩下第%d./n",delete_node(head,n,m));
    return(0);
}

 

 
原创粉丝点击