1. 程式人生 > >UVa11925 生成排列(Generating Permutations)---雙向迴圈連結串列

UVa11925 生成排列(Generating Permutations)---雙向迴圈連結串列

題目描述:給你一個特定序列,要求你經過一定的變換規則將升序列變為給的特定序列。

https://vjudge.net/problem/UVA-11925

變換規則為:1.第一個元素和第二個元素交換. 2、首元素到尾部。

題目分析:逆著處理,最後輸出的時候倒著輸出就行了。若第一個元素大於第二個元素則交換,否則將最後一個元素變為首元素。注意:到第一個元素是n時,不進行交換,否則會出現死迴圈。找到規則很重要,逆著處理的時候就是交換第一個和第二個,將尾部的元素 移動到第一個。使用迴圈連結串列只需要將head前移即可。

這個和題目中的描述是不同的,書上有錯誤。

另外,這裡使用了雙向迴圈連結串列,和堆疊,程式非常簡單。

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <sstream>
#include <malloc.h>
#include <iostream>
using namespace std;
typedef struct dnode {
	int data;
	struct dnode *prior;
	struct dnode *next;
} dnode;

dnode *add(dnode *dhead,int x);
dnode *del(dnode *dhead);
void printdnode(dnode *dhead);

dnode *add(dnode *dhead,int x) {
	dnode *s=NULL;
	dnode *p=NULL;
	s=(dnode *)malloc(sizeof(dnode));
	s->data=x;
	if(NULL==dhead) {
		dhead=s;
		s->next=s;
		s->prior=s;
	} else {
		p=dhead;
		//先找到新增的位置
//		while(1) {
//			if(s->data>p->data) {
//				p=p->next;
//				if(p==dhead) {
//					break;
//				}
//			} else {
//				break;
//			}
//		}
		//插入到p節點的前面
		p->prior->next=s;
		s->prior=p->prior;
		s->next=p;
		p->prior=s;
	}
	return dhead;
}

dnode *del(dnode *dhead) {
	int x=0;
	dnode *p=NULL;
	if(NULL==dhead) {
		printf("dlist empty\n");
		return NULL;
	}

	printf("請輸入刪除的資料:\n");
	scanf("%d",&x);
	p=dhead;

	//找到需要刪除資料的地址
	while(1) {
		if(p->data==x) {
			break;
		}
		p=p->next;
		if(p==dhead) {
			printf("no this data in dlist\n");
			return dhead;
		}
	}

	if(dhead==p) {
		dhead=dhead->next;
	}
	p->prior->next=p->next;
	p->next->prior=p->prior;

	if((dhead->next==dhead)&&(dhead->prior=dhead)&&(dhead->data==x)) {
		free(dhead);
		dhead=NULL;
		p=NULL;
	} else {
		free(p);
		p=NULL;
	}
	return dhead;
}

void printdnode(dnode *dhead) {
	if(NULL==dhead) {
		printf("dlist empty\n");
		return;
	}

	dnode *p=NULL;
	p=dhead;
	while(1) {
		printf("%d ",p->data);
		p=p->next;
		if(p==dhead) {
			break;
		}
	}
	printf("\n");
}
bool check(dnode *dhead,dnode *tail)
{
	dnode *p=dhead;
	while(p!=tail)
	{
		if(p->data>p->next->data)
		return false;
		p=p->next;
	}
	return true;
}
int main() {
	int n,t;
	stack<int> st;
	while(scanf("%d", &n)&&n) {
		if(n==1){
			//printf("\n");
			//continue;
		}
		while(!st.empty()) st.pop();
		dnode *dhead=NULL,*tail,p,q;
		for(int i=0; i<n; i++) {
			cin>>t;
			dhead=add(dhead,t);
		}
		tail=dhead->prior;
		while(!check(dhead,tail))
		{
			if(dhead->data>dhead->next->data&&dhead->data!=n)
			{
				t=dhead->data;
				dhead->data=dhead->next->data;
				dhead->next->data=t;
				st.push(1);
				//printdnode(dhead);
			}
			if(check( dhead,tail)) break;
			else
			{
				st.push(2);
				dhead=tail;
				tail=tail->prior;
				//printdnode(dhead);
			} 
		}
 	
	   	while(!st.empty()) 
	   {
	   	 cout<<st.top();
		 st.pop();
	   }
	   cout<<endl;	

	}
	return 0;
}