2020年12月24日
10年初搭建的原始的AOSP工程。不知道官網現在還能不能下載到。從內核到開發調試工具的所有東西都可以編譯出來,包括:內核、虛擬機、Framework、Java應用、手機模擬器、log工具、調試工具、開發用的Eclipse插件、SDK、、NDK等。
鏈接:https://gitee.com/zhulf753/repo/tree/master/Android/Ubuntu10.04
2018年6月23日
摘要: 經過別人在板子上幾天幾夜的測試,跑了6、7個任務同時開了4、5個中斷,CPU滿負荷。完全沒問題,已經用在產品上。主要就修改一個文件os_cpu_a.asm和任務創建時堆棧初始化代碼。花了兩天時間(以前沒接觸過cortex-m0也沒寫過匯編,多年沒接觸過單片機了)。以下是os_cpu_a.asm。有不少的草稿代碼,應該不影響閱讀的,請自行忽略。;***************************...
閱讀全文
2016年11月1日
摘要: 相關標準描述參考網站:http://www.fourcc.org/
參考解析工具和圖片參考網站:http://www.sunrayimage.com/examples.html
網上有很多解析YUV格式的工具,覺得還是sunrayimage的工具比較全還有示例圖片。
只有代碼,花半天時間折騰出來的。
Code highlighting produced by Actipro CodeHig...
閱讀全文
2008年1月11日
#include<iostream>
#include<deque>
#include <ctime>
using namespace std;
template<class _Ty, class _C = deque<_Ty> >
class zlfStack {
public:
typedef unsigned _Ty;
typedef _C::allocator_type allocator_type;
typedef _C::value_type value_type;
typedef _C::size_type size_type;
typedef _C::iterator zlfIterator;
protected:
_C c;
public:
inline
const value_type& zlfTop2(){
return *(c.end()-2);
}
inline
const value_type& zlfTop3(){
return *(c.end()-3);
}
inline
void top_3(value_type& x,value_type& y,value_type& b)
{
b=*(c.end()-1);
y=*(c.end()-2);
x=*(c.end()-3);
}
inline
void top_2(value_type& x,value_type& y)
{
y=*(c.end()-2);
x=*(c.end()-3);
}
//zlfStack(){ }
explicit zlfStack(const allocator_type& _Al = allocator_type())
:c(_Al){}
allocator_type get_allocator() const
{return (c.get_allocator()); }
bool empty() const
{return (c.empty()); }
size_type size() const
{return (c.size()); }
value_type& top()
{return (c.back()); }
const value_type& top() const
{return (c.back()); }
void push(const value_type& _X)
{c.push_back(_X); }
inline
void push_3(const value_type& x,const value_type& y,const value_type& b)
{
c.push_back(x);
c.push_back(y);
c.push_back(b);
}
inline
void pop()
{c.pop_back(); }
};///
enum{B0=0,B1=1,B2=2,B3=3};
int A(unsigned x,unsigned y)
{
static count=0;
if (!x&&!y) {return ++count;return count;}
if (x==0xffff) {count=0;return 0;}
if (x) A(--x,y);
AB1: if(y) A(x,--y);
AB2:
return count;
}
inline
void clear(){A(0xffff,0);}
zlfStack<unsigned> s;
inline
void push(unsigned x,unsigned y,unsigned b)
{
s.push(x);
s.push(y);
s.push(b);
}
inline
void pop(unsigned& x,unsigned& y,unsigned& b)
{
b=s.top();
s.pop();
// y=s.top();
s.pop();
// x=s.top();
s.pop();
}
int main()
{
unsigned x=1,y=1,b=1,c=0,z=0;
unsigned temp=0;
clock_t t1,t2;
unsigned k=1;
unsigned long sum1=0,sum2=0,time1=0,time2=0;
cout<<"AAAA"<<endl;
t1=clock();
for (x=1;x<10;x++) {
for (y=1;y<10;y++) {
clear();
k=A(x,y);
sum1+=k;
cout<<k<<" ";
cout<<"x="<<x<<" "<<"y="<<y<<endl;
}
}
t2=clock();
time1=t2-t1;
cout<<endl;
if (!x&&!y) return 0;//exit
sum2 = 0;
t1=clock();
for (x=1;x<10;x++) {
for (y=1;y<10;y++) {// push(x,y,B3);
s.push_3(x,y,B3);
c=0;
b=B0;
while (!s.empty()) {
switch(b) {
case B0:if(x) {//push(--x,y,B1);
s.push_3(--x,y,B1);
b=B0;continue;}
case B1:if(y) {//push(x,--y,B2);
s.push_3(x,--y,B2);
b=B0;continue;}
case B2:if (!x&&!y) c++;
default:;
}//switch
// pop(x,y,b);
b=s.top();
s.pop();
s.pop();
s.pop();
if(b==B3) break;//return to main
// pop(x,y,temp);
// push(x,y,temp);
// y=s.zlfTop2();
// x=s.zlfTop3();
s.top_2(x,y);
}//while
sum2+=c;
// cout<<"c="<<c<<" "<<"x="<<x<<" "<<"y="<<y<<endl;
}//y
}//x
t2=clock();
time2=t2-t1;
cout<<"time used :"<<time2<<"ms"<<endl;
cout<<"routines :"<<sum2<<endl;
cout<<endl<<endl;
double t;
cout<<"routines: "<<sum1<<" time1: "<<time1<<endl;
t=sum1/time1;
cout<<t<<" rps"<<endl;
cout<<"routines: "<<sum2<<" time2: "<<time2<<endl;
t=sum2/time2;
cout<<t<<" rps"<<endl;
return 0;
}
2008年1月10日
用http的get方法,構造要查詢的url,get下來,分析結果頁面即可
首先是構造url,以下是一些示例,主要看清楚?號后面的參數所代表的意思即可:
http://www.google.cn/search?num=100&&q=%E5%85%83%E6%90%9C%E7%B4%A2&start=10
http://www.baidu.com/s?wd=%D4%AA%CB%D1%CB%F7&rn=100&pn=10 //第二頁pn
http://www.yahoo.cn/s?p=%E5%85%83%E6%90%9C%E7%B4%A2&b=10 //第二頁b
http://search.yahoo.com/search?n=100&p=%E5%85%83%E6%90%9C%E7%B4%A2&b=101
http://cnweb.search.live.com/results.aspx?q=%E5%85%83%E6%90%9C%E7%B4%A2&first=51 //第二頁first=51
http://p.zhongsou.com/p?w=%D4%AA%CB%D1%CB%F7&b=3 //b=3表示第三頁
http://www.soso.com/q?w=%D4%AA%CB%D1%CB%F7&num=20&pg=1 //第一頁,每頁20個
第二步是解釋搜索結果頁面:
<meta http-equiv="content-type" content="text/html;charset=gb2312">
Google
搜索結果個數的字符串前綴:約有<b> //獲取個數用字符串定位的方式
搜索結果開始的標簽:<div id=res> //也可以用字符串定位的方式,要準確就用查找標簽定位的方式
各個搜索結果的開始標簽:<div class=g> //字符串定位的方式
搜索結果的url在第一個<a target=_blank class=l>標簽里頭
搜索結果的標題在<a></a>的標簽之間
搜索結果的摘要在接下來的<table><tr><td>標簽里頭直到<b>...<b><br>
搜索結果的重寫的url在<b>...<b><br>之后的<span>標簽里頭,格式為:url,一個空格,網頁大小
搜索結果的網頁快照在接下來的<a class=fl>的標簽里頭,屬性中有url,標簽之間有網頁快照文字
接下來還有類似網頁等,都在<a class=fl>標簽里頭
各個搜索結果的結束標簽是</td></tr></table></div>
......................
相關搜索的開始標簽:<p class=e>
在接下來的各個<a></a>標簽之間的內容就是相關搜索的內容
直到標簽<br clear=all>就可以結束了
Baidu
搜索結果個數的字符串前綴:<td align=\"righ,在定位該字符串后,直到</td>,即在這個td標簽之內含有的字符串包含相關網頁數和用時
搜索結果開始的標簽:<DIV id=ScriptDiv></DIV>
各個搜索結果的開始標簽:<table
搜索結果的url在第一個<a target=_blank class=l>標簽里頭
搜索結果的標題在<a></a>的標簽之間,以<br>標簽結束
搜索結果的摘要以<br>開始直到下一個<br>標簽
接下來的一行(<br>換行)的font標簽中有搜索結果url的重寫,一個空格,網頁大小,網頁時間
在接下來會有一些<a>標簽如百度快照,直到又一個<br>
然后搜索結果的結束標簽</table>
.........................
導航條的開始標簽:<br clear=all>
導航條的內容在開始標簽之后的<div class="p"></div>標簽之間
相關搜索在接下來的<div>標簽之間的各個<a>標簽之內
其他考慮:對于字符串的匹配可以利用kmp,注意到匹配搜索結果各部分的時候所用到的模式字符串的最大前綴字符串最多是一個字符,這樣可以避免求取最大前綴字符串從而提高效率;如果要精確地匹配還需要弄兩個函數,一個用來構造標簽,一個用來讀取標簽之間的文本。
2007年10月8日
主要就是解釋readobject和writeobject函數,應該夠了,至于在DOC/VIEW模型種使用的話,應該很簡單的
0---空指針 7FFF---大索引號標志,即后面的索引號是32位的
0X8000---保留以后使用 0XFFFF---新類的定義
小索引對象或者類的索引號:1~~~7FFE,但是類的最高位是1
對象的插入:writeobject函數:(全局插入<<函數只是調用了這個函數)首先插入類信息,然后是對象信息。每次寫入(即一次writeobject函數的執行流程)是下面三種的之一:
1 若是未寫過的類并且未被寫過的對象:
1.1 寫入新類標志:0XFFFF *this << wNewClassTag;
1.2 寫入類的版本號,寫入類名的字符串長度:ar << (WORD)m_wSchema << nLen;
1.3 寫入類名 ar.Write(m_lpszClassName, nLen*sizeof(char));
1.4 寫入對象 ((CObject*)pOb)->Serialize(*this);
2 若是曾經寫過的類并且未寫過的對象:
2.1 寫入類的索引號 nClassIndex = (DWORD)(*m_pStoreMap)[(void*)pClassRef]
如果是小索引類:則寫入類*this << (WORD)(wClassTag | nClassIndex);
如果是大索引類:則寫入大索引號標志(7FFF)和32位的類索引號(最高位是1) *this << wBigObjectTag;
*this << (dwBigClassTag | nClassIndex);
2.2 寫入對象 ((CObject*)pOb)->Serialize(*this);
3 若是曾經寫過的類并且曾經寫過的對象:
3.1 寫入對象的索引號
如果是小索引對象:則直接寫入索引號*this << (WORD)nObIndex;
如果是大索引對象:則寫入大索引號標志和32位的對象索引號(最高位是0)
*this << wBigObjectTag;
*this << nObIndex;
以上3種情況的寫入都是首先寫入一個字,這個字的內容就代表了之后字節即類信息的意義或者可以只是一個對象的索引號(情況三),即是新類(字節為0xFFFF)還是已經定過的小索引類(索引號從0x8001—0xFFFE)又或者是已經定義過的大索引類以(字節0x7FFF后續兩個字節為索引號)。
對于讀取上面文件格式的信息并且區分出將要讀取的是類還是對象,是索引還是對象數據,在readObject中
首先讀取一個字如果是0XFFFF則顯然對應的是第一種情況,此時可以容易地讀取數據;如果第一個字的最高位是1的話,很顯然此時對應的就是第二種情況,即該字是一個類的索引號,而且是小索引類;如果是0x7FFF則此時對應的就是第三種情況大索引號對象或者第二種情況大索引號類;如果最高位不是1則此時對應的也是第三種情況但是小索引對象;在區分了第一個字以后就可以容易地讀取后面的數據。這樣每次的readObject函數的調用都只是提取以往某次writeObject函數寫入的數據。
對象的提取:ReadObject函數,因為在宏IMPLEMENT_SERIAL里定義的提取操作符只是簡單地調用了這個函數。首先提取類信息,以便正確地動態生成對象,然后是對象信息。
PS:m_pStoreMap里即包含了已經序列化的類(CRuntimeClass)和對象的指針。
UINT CArchive::GetObjectSchema()函數只能調用一次,一般該函數在某個類(ar正在序列化的類)的Serialize函數里頭調用,它返回讀取的類的版本號。以下幾行來自readObject:
UINT nSchemaSave = m_nObjectSchema;
m_nObjectSchema = nSchema;
pOb->Serialize(*this);
m_nObjectSchema = nSchemaSave;
一般地,也正是在serialize里頭來處理各種版本的序列化。
FAQ:
1. 為什么可以定義全局的插入操作符,而提取操作符卻要對每個類在宏里頭聲明?
插入操作的是在已知對象所有信息的情況下的操作,包括對象的類型和狀態,類信息的寫入使用CruntimeClass非靜態成員函數Store來實現的,而GetCRuntime成員函數又是虛函數所以可以用指向COBJECT的指針來正確地獲取,然后正確地調用STORE函數;而對于提取操作,將要提取出的對象的類型和狀態都是未知,提取類信息主要是用CruntimeClass的靜態成員LOAD來獲取,該成員獲得文件中類信息之后通過查找全局的類型鏈表可以唯一地確定一個CrutimeClass類型的靜態對象,通過該對象的createObject函數可以構造出即將提取的對象類型,然后利用動態構造的對象的序列化函數就可以正確地提取出對象,因為
1.1 在宏定義的提取操作符中classname參數是無法用COBJECT類來替換,因為如果替換的話則在提取信息過程中即使出現錯誤,比如說提取出的類型根本就不是可序列化的但是如果繼承自COBJECT的話仍然可以通過錯誤檢查。
2007年10月5日
#include <math.h>
#include <vector>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
template<typename E>
class AVL_TMP
{
template <typename E>
class AVL_NODE
{
public:
AVL_NODE():ln(0),rn(0),depth(0){}
AVL_NODE( const E& e):data(e),ln(0),rn(0),depth(0){}
~AVL_NODE(){ if (ln) delete ln; if (rn) delete rn; }
bool operator < (E& e){ return data < e; }
bool operator > (E& e){ return data > e; }
bool operator == (E& e){ return data == e; }
bool operator != (E& e){ return data != e; }
E getdata(){return data;}
E data;
int depth;
AVL_NODE<E> *ln,*rn;
};
public:
typedef E dataType;
typedef AVL_TMP<E> Myt;
typedef AVL_NODE<E> n;
typedef n* npos;
typedef npos iterator;
enum unbalanceType {LL,RR,LR,RL};
AVL_TMP():root(0),size(0),depth(-1){}
~AVL_TMP(){ if(root) delete root; }
iterator begin(){return root;}
bool insert(const E& e);
npos find(const E& e);
npos findpre(const E& e);
bool del(dataType);
bool balance(AVL_TMP<E>::iterator pos){
if(pos == NULL) throw 0;
int lh,rh;
if(pos->ln == NULL ) lh = -1;
else lh = pos->ln->depth;
if(pos->rn == NULL ) rh = -1;
else rh = pos->rn->depth;
return abs( lh - rh ) < 2 ;
}
virtual void frontOrder(){};
virtual void midOrder(){ };
protected:
void LLr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos);
void LRr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos);
void RRr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos);
void RLr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos);
void updateDepth(AVL_TMP<E>::iterator pos);
bool delAux(E const& e,AVL_TMP<E>::iterator pos = NULL);
iterator findMax(iterator );
iterator findMin(iterator );
bool upTree(int iDepth,iterator itRoot,unsigned long iSize){depth = iDepth;root = itRoot;size = iSize; return true;}
bool upRoutineDepth(vector<iterator>&);
bool adjust(iterator a,iterator b,iterator c,iterator prePos = NULL);
npos root;
int depth;
unsigned long size;
};
template<typename E>
bool AVL_TMP<E>::adjust(iterator a,iterator b,iterator c,iterator prePos){
bool b1,b2;
b1 = b == a->ln;
b2 = c == b->ln;
unbalanceType ub;
if(b1&&!b2) ub = LR;
if(!b1&&b2) ub = RL;
if(b1&&b2) ub = LL;
if(!b1&&!b2) ub = RR;
switch(ub) {
case LL :LLr(a,prePos);
break;
case LR :LRr(a, prePos);
break;
case RR :RRr(a,prePos);
break;
case RL :RLr(a,prePos);
break;
} //end switch
return true;
}
template<typename E>
bool AVL_TMP<E>::upRoutineDepth(vector<iterator>&routine){
//該函數主要是將路徑節點的深度更新并且使得那些不平衡的節點平衡
int size = routine.size();
while (size--) {
updateDepth(routine[size]);
if (!balance(routine[size])) {//不平衡得調整
iterator cur = routine[size],prePos = NULL;
if(size-1>=0)
prePos = routine[size-1];
//檢查當前不平衡節點的哪顆子樹的高度更高
bool bl = cur->ln != NULL;
bool br = cur->rn != NULL;
if (!bl) {//肯定有右孩子
if(cur->rn->ln) RLr(cur,prePos);
else RRr(cur,prePos);
}
else{//有左孩子
if (!br) {//沒右孩子
if (cur->ln->ln) LLr(cur,prePos);
else LRr(cur,prePos);
}
else{ //有右孩子,此時需要檢查左右孩子的高度,則右子樹高度至少為1
//因此左子樹高度至少為3,則左子樹的節點個數肯定大于4
if (cur->ln->depth > cur->rn->depth) LLr(cur,prePos);
else RRr(cur,prePos);
}
}
}
}
return true;
}
template<typename E>
AVL_TMP<E>::iterator AVL_TMP<E>::findMax(AVL_TMP<E>::iterator pos){//以pos為根的樹的最大值的節點
if (!pos) return NULL;
iterator p = pos;
while(p->rn) p = p->rn;
return p;
}
template<typename E>
AVL_TMP<E>::iterator AVL_TMP<E>::findMin(AVL_TMP<E>::iterator pos){
iterator p = pos;
while (p->ln) p = p->ln;
return p;
}
template<typename E>
void AVL_TMP<E>::updateDepth(AVL_TMP<E>::iterator pos){
bool b1 = pos->ln == NULL,b2 = pos->rn ==NULL;
switch(b1) {
case true:
if(b2) pos->depth = 0;
else pos->depth = pos->rn->depth+1;
break;
default: //false
if(b2) pos->depth = pos->ln->depth+1;
else pos->depth = max(pos->ln->depth , pos->rn->depth )+1;
}
if(pos == root) depth = pos->depth;
}
template<typename E>
void AVL_TMP<E>::LLr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos){
typename AVL_TMP<E>::iterator t, a = pos, b = t = pos->ln ;
pos->ln = t->rn;
t->rn = pos;
if(root == a) root = b;
if(prePos != NULL)
if(prePos->ln == a) prePos->ln = b;
else prePos->rn = b;
updateDepth(a);updateDepth(b);
}
template<typename E>
void AVL_TMP<E>::LRr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos){
AVL_TMP<E>::iterator a = pos,b = pos ->ln, c = b->rn;
b->rn = c->ln ; a->ln = c->rn;
c->ln = b; c->rn =a;
if(a == root ) root = c ;
if(prePos != NULL)
if(prePos->ln == a) prePos->ln = c;
else prePos->rn = c;
updateDepth(a);updateDepth(b);updateDepth(c);
}
template<typename E>
void AVL_TMP<E>::RRr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos ){
AVL_TMP<E>::iterator a = pos ,t, b = t = pos->rn ;
pos->rn = t->ln;
t->ln = pos;
if(prePos != NULL)
if(prePos->ln == a) prePos->ln = b;
else prePos->rn = b;
if(root == a) root = b;
updateDepth(a);updateDepth(b);
}
template<typename E>
void AVL_TMP<E>::RLr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos){
AVL_TMP<E>::iterator a = pos, b = pos->rn , c = b->ln;
a->rn = c->ln ; b->ln = c->rn;
c->ln = a; c->rn = b;
if(prePos != NULL)
if(prePos->ln == a) prePos->ln = c;
else prePos->rn = c;
if( a == root) root = c;
updateDepth(a);updateDepth(b);updateDepth(c);
}
template<typename E>
bool AVL_TMP<E>::insert(const E& e){
if(root == NULL) {root = new AVL_NODE<E>(e); size++; depth = root->depth;return true;}
bool bUpdateDepth = false;
vector<AVL_TMP<E>::iterator> routin;
typename AVL_TMP<E>::iterator p = root,pos,prePos;
for (int i = 0 ; i < size ;i++ ) {
routin.push_back(p);
if(p->data > e){
if ( p->ln == NULL ) {
p->ln = pos = new AVL_NODE<E>(e);
bUpdateDepth = p->rn == NULL;
break;
}
else { p = p->ln ; continue;}
}
if(p->data < e){
if (p->rn == NULL) {
p->rn = pos = new AVL_NODE<E>(e) ;
bUpdateDepth = p->ln == NULL;
break;
}
else { p = p->rn ; continue;}
}
return false; //already exists
} //insertion finished
size++;
if(size <= 2 ) {
updateDepth(root);
return true;
}
if(!bUpdateDepth) return true; //balance
bool unAdjusted = true;
// check for balance and adjust depth
for (i = routin.size()-1; i >=0 ; i-- ) {
if(!balance(routin.at(i)))
if(unAdjusted) { // unbalance! get unbalance type
if(i-1 >= 0) prePos = routin.at(i-1);
else prePos = NULL;
AVL_TMP<E>::iterator a = routin.at(i) , b = routin.at(i+1) , c;
if(i+2 >= routin.size() ) c = pos;
else c = routin.at(i+2);
bool b1,b2;
b1 = b == a->ln;
b2 = c == b->ln;
unbalanceType ub;
if(b1&&!b2) ub = LR;
if(!b1&&b2) ub = RL;
if(b1&&b2) ub = LL;
if(!b1&&!b2) ub = RR;
switch(ub) {
case LL :LLr(routin.at(i),prePos);
break;
case LR :LRr(routin.at(i),prePos);
break;
case RR :RRr(routin.at(i),prePos);
break;
case RL :RLr(routin.at(i),prePos);
break;
} //end switch
unAdjusted = false;
} //end if
updateDepth(routin.at(i)); //update the depth of the node in the routin
depth = root->depth;
}//end for
return true;
};
template<typename E>
AVL_TMP<E>::npos AVL_TMP<E>::find(const E& e){//search for position
npos p=root;
while (p&&p->data!=e)
if(e>p->data) p=p->rn;
else p= p->ln;
return p;
}
template<typename E>
AVL_TMP<E>::npos AVL_TMP<E>::findpre(const E& e){//search for parent node position
npos p,pre;
p=pre=root;
while (p&&p->data!=e) {
pre = p;
if (e>p->data) p=p->rn;
else p = p->ln;
}
if(p) if(p->data==e) return NULL;//already existed
return pre;
}
template<typename E>
bool AVL_TMP<E>::delAux(E const& e,AVL_TMP<E>::iterator pos){
// 1.遞歸刪除節點,直到刪除的是葉子節點
// 2. 刪除葉子節點,更新樹的數據成員
// 3. 更新路徑上的節點深度并且檢查平衡因子
static vector<iterator> routine;
iterator p = pos;
bool bUpdate = false;
if(!pos){//第一次調用
p = root;
while (p&&e!=p->data) {//找到節點,并且將尋找路徑存入表中
routine.push_back(p);
if(p->data > e) p = p->ln;
else p = p->rn;
}
if(p == NULL){ //沒找到
routine.clear();
return false;
}
else pos = p;
}
if (pos->ln||pos->rn) {//不是葉子節點,則該節點有孩子節點,可能是一個或者兩個
routine.push_back(pos);//還得往下刪除
if (pos->ln&&!pos->rn){ //情況一: 只有有左孩子
//找到左子樹中的最大值的位置
iterator max = pos->ln;
while (max->rn) { routine.push_back(max); max = max->rn;}
bUpdate = false;
//偽刪除
pos->data = max->data;
delAux(max->data,max);
}
else if (!pos->ln&&pos->rn) { //情況二:只有右孩子
//找到右子樹中的最小值
iterator min = pos->rn;
while (min->ln) { routine.push_back(min); min = min->ln;}
bUpdate = false;
//偽刪除
pos->data = min->data;
delAux(min->data,min);
}
else //情況三:有倆個孩子
{
//找到左子樹中的最大值
iterator max = pos->ln;
while (max->rn) { routine.push_back(max); max = max->rn;}
bUpdate = false;
//偽刪除
pos->data = max->data;
delAux(max->data,max);
}
}
else
{//是葉子節點
//有三種情況,是其父節點的左子樹且沒有兄弟,是其父節點的右子樹且沒有兄弟,有兄弟
//取得其父節點
iterator parent = NULL;
if (routine.size()) //有父節點
parent = routine[routine.size()-1];
else{//即該節點是根節點,無根節點
delete root;
routine.clear();
upTree(-1,NULL,0);
return true;
} //完成根節點的刪除
//有父節點
if (pos == parent->ln&&!parent->rn) {//情況一:是父節點的左孩子且沒兄弟
//刪除節點
parent->ln = NULL;
delete pos;
//需要更新路徑上的節點的深度
bUpdate = true;
upRoutineDepth(routine);
upTree(root->depth,root,size-1);
routine.clear();
//改寫父節點的孩子指針
}//完成情況一葉子節點的刪除
else{
if (pos == parent->rn && !parent->ln ) { //情況二:是父節點的右孩子且沒兄弟
parent->rn = NULL;
delete pos;
bUpdate = true;
upRoutineDepth(routine);
upTree(root->depth,root,size-1);
routine.clear();
}//完成情況二葉子節點的刪除
else{//情況三:有兄弟
//只需要將節點刪除,并清理路徑表就可以了
if (pos == parent->ln) parent->ln = NULL;
else parent->rn = NULL;
delete pos;
routine.clear();
}//完成情況三的葉子節點刪除
}
}
return true;
}
template<typename E>
bool AVL_TMP<E>::del(dataType e){
return delAux(e);
}
2007年9月14日
#include <iostream.h>
#include<io.h>
const int QUENS = 7;
int getcol(int q[],int n,const int firstCol)
{//q表示每個皇后的列位置,firstCol是搜索列位置時的起始位置
//n表示正在搜索第n個皇后的列位置,皇后的名稱從0--n編號,也是皇后的行號
bool b = true;
int i = firstCol;
for (i = firstCol; i<=QUENS ; i++) {
for (int j=0; j<n; j++) {
if(q[j] == i || (n+q[j]==i+j)||(n+i == j+q[j])){
b = false;
break;
}
}
if(j == n)
return i;
else if(firstCol > QUENS) return firstCol;
}
if(!b) return QUENS+1;
}
void EQ(int q[],int n){
void disp(int[]);
int col = QUENS+1;
bool b = true;
int firstCol = 0;
while (QUENS >= (col=getcol(q,n,firstCol))){
if(QUENS == n){
q[n] = col;
disp(q);
return ;
}
else{
q[n] = col;
firstCol = col +1;
EQ(q,n+1);
}
}
}
void disp(int q[])
{//顯示一種排列
static count = 0;
count++;
cout<<"number "<<count<<" : ";
for (int i=0; i<=QUENS; i++)
cout<<q[i]+1<<" ";
cout<<endl;
}
void outTofile()
{//由于結果比較多,所以把結果重定向輸出到文件里頭了,文件名是EightQuen.txt
int old = _dup(1);
FILE* pf;
pf = fopen("EightQuen.txt","w");
if(!pf) throw 0;
_dup2((fileno(pf)),_fileno(stdout));
int q[8];
EQ(q,0);
fclose(pf);
_dup2(old,_fileno(stdout));
}
void main()
{
outTofile();
}