同前几篇博客
算法:组合数学中文第4版 机械工业出版社 P57
这个版本好像小范围发布过,这么多注释......
//////////////////////////////////////////////
// //
// Project Name: Permutation //
// //
// File Name: permutation.h //
// //
// Author: Victor Zhang //
// //
// ID: 21*****92 //
// //
// Create Date: March 23. 2009 //
// //
//////////////////////////////////////////////
#include <iostream>
using namespace std;
#ifndef PERMUTATION_H
#define PERMUTATION_H
struct unit//定义元素结构
{
unit* pre;//指向前驱元素的指针
bool arrowLeft;//元素箭头指向
int value;//元素的值
unit* next;//指向后继元素的指针
};
class Permutation_usr
{
private:
unit* head;//链表头地址 (变量)
int count;//链表长度 (变量)
unit* activeUnit;//链表最大活动数所在元素的地址 (变量)
bool newUnit(unit*, int); //添加元素,并给新元素赋值 (函数)
bool deleteUnit(unit*); //删除指定地址的元素 (函数)
bool setUnitArrow(bool, unit*); //设置元素的箭头指向 (函数)
bool getUnitArrow(unit*); //获取元素的箭头指向 (函数)
bool isActiveUnit(unit*);//判断元素是否为活动数 (函数)
void findMaxActiveUnit();//查找最大活动数所在的元素 (函数)
bool exchangeUnits(unit*);//交换目标元素和其箭头所指向的与其相邻的元素的位置(函数)
bool setUnitValue(int, unit*); //设置元素的值 (函数)
int getUnitValue(unit*); //获取元素的值 (函数)
public:
Permutation_usr()//初始化链表
{
head = activeUnit = NULL;
count = 0;
};
Permutation_usr(int);//初始化含n个元素的链表
~Permutation_usr()//销毁链表
{
deleteAllUnits();//删除链表中的所有元素
head = activeUnit = NULL;
count = 0;
};
bool newUnits(int);//重建n个新元素,并自动赋值 (函数)
bool deleteAllUnits();//删除head之后的所有元素 (函数)
void prtQueue();//打印链表 (函数)
void proccess();//执行排列 (函数)
};
#endif
//////////////////////////////////////////////
// //
// Project Name: Permutation //
// //
// File Name: permutation.cpp //
// //
// Author: Victor Zhang //
// //
// ID: 21*****92 //
// //
// Create Date: March 23. 2009 //
// //
//////////////////////////////////////////////
#include<iostream>
using namespace std;
#include"permutation.h"
Permutation_usr::Permutation_usr(int n) //初始化含n个元素的链表
{
this->activeUnit = this->head = NULL;
this->count = 0;
if (!(this->newUnits(n))) /*若初始化失败给出提示信息*/
cout<<"Error in creating units.\n";
};
bool Permutation_usr::newUnit(unit* a, int m_value) //添加元素,并给新元素赋值
{
unit* p_item = new unit;
if (!(p_item)) return false; /*若初始化失败,则返回失败*/
p_item->arrowLeft = true;
p_item->pre = a;
p_item->value = m_value;
if (this->count > 0) /*判断链表中是否有元素*/
{ /*链表中已有元素*/
p_item->next = a->next;
if (a->next) a->next->pre = p_item;
a->next = p_item;
}
else /*链表中无元素*/
{
p_item->next = NULL;
this->head = p_item; /*设置链表头地址*/
};
this->count++;
return true;
};
bool Permutation_usr::newUnits(int n) //重建n个新元素,并自动赋值
{
unit* p_target = NULL;
int i;
if (n <= 0) return false;
if (n < this->count) /*为提高重用时的效率,判断新建元素个数与原有元素之间的大小关系*/
{ /*新链表元素个数小于原链表元素个数,则初始化元素箭头方向,并删除多余元素*/
p_target = this->head; //获取头地址
for (i = 1; i <= n; i++)
{
head = head->next; //获取要删除的多余元素的首地址
};
this->deleteAllUnits(); //删除多余元素
head = p_target; //更新头地址
for (i = 1; i<= n; i++)
{
this->setUnitArrow(true, p_target); //初始化箭头方向
if (i == n) p_target->next = NULL; //末尾元素
p_target = p_target->next; //移动指针
};
}
else if (n == this->count) /*新链表元素个数等于原链表元素个数,则初始化元素箭头方向*/
{
p_target = this->head;
while (p_target)
{
this->setUnitArrow(true, p_target);
p_target = p_target->next;
};
}
else /*新链表元素个数大于原链表元素个数,则初始化元素箭头方向,并删除多余元素*/
{
for (i = 1; i < this->count; i++) //重置已有元素(不含末位)箭头方向
{
this->setUnitArrow(true, p_target);
p_target = p_target->next;
};
this->setUnitArrow(true, p_target); //重置末位元素箭头方向
for (i = (this->count + 1); i <= n; i++)
{
if (!(this->newUnit(p_target, i))) return false; //新建元素
if (p_target) p_target = p_target->next; //判断所创元素是否为链表首元素,不是则移动指针
else p_target = this->head; //是则将指针指向该元素
};
};
return true;
};
bool Permutation_usr::deleteAllUnits() //删除head之后的所有元素
{
unit* p_tmp, *p_nxt;
p_tmp = p_nxt = head;
while (p_tmp)
{
p_nxt = p_tmp->next; //获取后继元素地址
this->deleteUnit(p_tmp); //删除当前元素
p_tmp = p_nxt; //将操作指针指向后继元素
};
return true;
};
bool Permutation_usr::deleteUnit(unit* a) //删除指定地址的元素
{
if (!(a)) return true;
if (this->activeUnit == a) this->activeUnit = NULL;
unit* m_nxt = a->next; //获取指定元素后继
unit* m_pre = a->pre; //获取指定元素前驱
if (m_nxt) //重新连接链表
{
if (m_pre)
{
m_nxt->pre = m_pre;
m_pre->next = m_nxt;
}
else
{
m_nxt->pre = NULL;
head = m_nxt;
};
}
else
{
if (m_pre)
m_pre->next = NULL;
else
this->head = NULL;
}; //完成连接
delete a; //删除元素
this->count--; //计数器减一
return true;
};
bool Permutation_usr::setUnitArrow(bool isArrowLeft, unit* a) //设置元素的箭头指向
{
if (a)
{
a->arrowLeft = isArrowLeft;
return true;
}
else
return false;
};
bool Permutation_usr::getUnitArrow(unit* a) //获取元素的箭头指向
{
if (a) return a->arrowLeft;
return false;
};
void Permutation_usr::findMaxActiveUnit() //查找最大活动数所在的元素
{
unit* p_tmp;
p_tmp = this->head;
int m_curUnitValue = 0;
int m_curMaxValue = 0;
if (this->activeUnit) m_curMaxValue = this->activeUnit->value; //获取当前最大活动数的值
while (p_tmp)
{
m_curUnitValue = p_tmp->value;
if (this->isActiveUnit(p_tmp) && m_curUnitValue > m_curMaxValue) //当前指针所指元素为活动元素,且其值大于当前最大活动数的值
{
this->activeUnit = p_tmp; //更改当前最大活动数的信息
m_curMaxValue = this->activeUnit->value;
};
p_tmp = p_tmp->next; //移动指针
};
};
bool Permutation_usr::isActiveUnit(unit* a) //判断元素是否为活动数
{
if (!(a)) return false;
if (a == this->head && this->getUnitArrow(a) == true) return false;
if (a->next == NULL && this->getUnitArrow(a) == false) return false;
if (this->getUnitArrow(a))
{
if (this->getUnitValue(a->pre) < a->value)
return true;
}
else
{
if (this->getUnitValue(a->next) < a->value)
return true;
};
return false;
};
bool Permutation_usr::exchangeUnits(unit* a) //交换目标元素和其箭头所指向的与其相邻的元素的位置
{
if (!(a)) return false;
unit* p_pre, * p_next;
p_pre = p_next = NULL;
if (this->getUnitArrow(a) ==true) //确定需要交换的两元素,并用指针指向此两元素
{
p_pre = a->pre;
p_next = a;
}
else
{
p_pre = a;
p_next = a->next;
}; //元素确定及指向完毕
if (!(p_pre && p_next)) return false;
if (p_pre->pre) //开始重新构造链表。判断第一个元素是否有前驱
p_pre->pre->next = p_next; //有则将前驱的后继指针指向第二个元素
else
head = p_next; //没有则将链表头地址指向第二个元素
if (p_next->next) //判断第二个元素是否有后继
p_next->next->pre = p_pre; //有则将后继的前驱指针指向第一个元素
p_pre->next = p_next->next; //将第一个元素的后继指针指向第二个元素的后继
p_next->pre = p_pre->pre; //将第二个元素的前驱指针指向第一个元素的前驱
p_pre->pre = p_next; //将第一个元素的前驱指针指向第二个元素
p_next->next = p_pre; //将第二个元素的后继指针指向第一个元素
return true; //完成链表的重构
};
bool Permutation_usr::setUnitValue(int m_value, unit* a) //设置元素的值
{
if (!(a)) return false;
a->value = m_value;
return true;
};
int Permutation_usr::getUnitValue(unit* a) //获取元素的值
{
if (!(a)) return 0;
return (a->value);
};
void Permutation_usr::prtQueue() //打印链表
{
unit* p = this->head;
while (p)
{
cout<<p->value<<" ";
p = p->next;
};
cout<<endl;
};
void Permutation_usr::proccess() //执行排列
{
this->prtQueue();
unit* tmp = this->head;
this->activeUnit = NULL;
this->findMaxActiveUnit(); //求最大活动数M
while (this->activeUnit) //进入while循环
{
this->exchangeUnits(this->activeUnit); //交换M和其箭头所指向的与其相邻的整数
while (tmp) //交换所有满足p>m的整数p的方向
{
if (this->getUnitValue(tmp) > this->getUnitValue(this->activeUnit))
this->setUnitArrow(!(this->getUnitArrow(tmp)),tmp);
tmp = tmp->next;
};
tmp = this->head; //重置activeUnit、tmp
this->activeUnit = NULL;
this->prtQueue(); //输出
this->findMaxActiveUnit(); //求最大活动数,继续循环
};
};
//////////////////////////////////////////////
// //
// Project Name: Permutation //
// //
// File Name: main.cpp //
// //
// Author: Victor Zhang //
// //
// ID: 21*****92 //
// //
// Create Date: March 23. 2009 //
// //
//////////////////////////////////////////////
#include<iostream>
using namespace std;
#include"permutation.h"
void main()
{
int n = 0;
cout<<"Please input n:";
cin>>n;
Permutation_usr a(n);
a.proccess();
system("pause");
};
来源:oschina
链接:https://my.oschina.net/u/120899/blog/14601