約瑟夫問題(c++)

           今天花幾小時完成了數據結構的實驗題,裏面實現了循環單鏈表的構建,節點的刪除。

           但說句實話,裏面的執行函數我寫的時候就有點彆扭,覺得不太好,有點混亂,雖然最終還是實現出來了,供大家參考,也希望有朋友指點改進一下!奮鬥

           編譯結果:

           

    

           源代碼:

           

#include<iostream>
using namespace std;
int T=1;//定義一個全局變量T用以計算操作次數
//定義一個約瑟夫節點結構體j_node
//------------------------------
struct j_node
{
	int data;   //節點保存的數據
	j_node *next; //指向下一節點的指針
};
//循環鏈表的賦值
//---------------------
j_node *Initnode(int n) //參數n是總共的節點數	
{
	int temp_date = 0;
	int i = 0;
	j_node *head; //定義節點的頭指針
	j_node *p;   
	head=p=new j_node;  //新創建節點
	cout<<"請輸入"<<n<<"個數字:"<<endl;
    for(i=1; i<=n; i++)
	{
		cout<<"第"<<i<<"個:";
		cin>>temp_date;             //輸入的節點數據temp
		p->data=temp_date;			//將輸入的節點數據賦值給節點
		if(i < n)
		{
		p->next=new j_node;		//節點指針指向新創建的節點
		p=p->next; //指針後移
		}
		else
			if(i == n)
			{
				p->next=head;  //已經到達尾節點,讓其指向頭結點,以構成循環鏈表
				break;
			}
	}
	cout<<p->next->data<<endl;//將尾節點的下一節點輸出,以驗證是否構成循環鏈表
	return head;//返回頭指針
}
//------------------
//鏈表輸出函數
void Output_node(j_node *head, int n)  //參數分別是頭指針head,節點總數n
{
     j_node *p;
	 p = head;
	 for(int i=0; i<n; i++)
	 {
		 cout<<p->data<<" ";
		 p = p->next;
	 }
	 cout<<endl;
}
//-------------------------------
//執行函數
void Done(j_node *head,int n, int a, int b) //參數分別是頭指針head,節點總數n,第一個報數的號l,報數的號碼m
{
	j_node *p;     //計數指針
	j_node *front; //存放刪除前節點
	j_node *back;  //存放刪除後節點
	j_node *del;   //存放刪除節點
	j_node *new_head;//存放新的頭指針
	p = front = head;
	//-----------------
	//這個for循環作用:找出第一個報數的節點
	for(int i=1; i<b; i++)
	{
		front = p;
        p = p->next;
	}
	//----------------
	while(head!=NULL)
	{
		//判斷當n==1時,也就是鏈表剩下最後一個節點時,結束刪除
			if(n==1)
		{
				cout<<"最後一個報數的是:"<<head->data<<endl;
			cout<<"問題已解決!"<<endl;
			return;
		}
	//-------------------------------
	//這個for循環的作用是找出要刪除的節點,及其後的節點
	for(i=0;i<a;i++,p = p->next)
	{ 
		if(i==a-2)
		{
			front=p;//要刪除的前一個節點
		}
		del = p;//要刪除的節點
		back = p->next;//要刪除的後一個節點
	}
	//------------------------------------
	    front->next=back;//要刪除的前節點指向要刪除的後節點
		//------------
		//判斷如果要刪除的是頭結點的話,就讓del->next成爲新的頭結點
		if(del==head)
		{
			new_head=del->next;
			head = new_head;//新的頭結點賦值給頭結點
		}
		cout<<"第"<<T<<"次刪除的節點是:  "<<del->data<<endl;
		delete del;//刪除節點
		n--;//鏈表的長度減一
		cout<<"第"<<T<<"次操作之後的鏈表是:  ";
		T++;
		Output_node(head,n);//輸出刪除節點後鏈表的情況
		cout<<endl;
		p = back; //讓刪除節點的後一個付給p,以構成循環計算
	}
}
//--------------------------
//主函數
int main()
{
	j_node *head;	
	int a,n,b;
	char c;
	while(1)
	{
    cout<<endl;
	cout<<"請分別輸入總人數 n:"<<endl;
	cin>>n;
	head=Initnode(n);//頭結點指向初始化好的循環鏈表
	cout<<"所創建的鏈表爲:"<<endl;
	Output_node(head,n);
	cout<<"請輸入第一個報數的號碼:"<<endl;
	cin>>b;
	cout<<"請輸入報的號數:"<<endl;
	cin>>a;
	if(b>n)
	{
		cout<<"輸入報數的號碼不合法!"<<endl;
		cout<<"請再次輸入: ";
		cin>>a;
	}
	Done(head,n,a,b);
	cout<<"是否再來一次(Y or N): ";
	cin>>c;
	if(c=='N')
		exit(0);
	else
		continue;
	}
	return 0;			
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章