int MaxSubSeqSum(int arrays[],int length){ int i,j,k,thisSum=0,maxSum=0; for(i=0;i<length;i++){ for(j=i;j<length;j++){ thisSum=0; for(k=i;k<=j;k++){ thisSum+=arrays[k]; } if(thisSum>maxSum)maxSum=thisSum; }; } return maxSum; }
int MaxSubSeqSum(int arrays[],int length){ int i,j,thisSum=0,maxSum=0; for(i=0;i<length;i++){//i是子列左端 thisSum=0;//從arrays[i]到arrays[j]的子序列和 for(j=i;j<length;j++){//j是子序列右端 thisSum+=arrays[j]; if(thisSum>maxSum)maxSum=thisSum;//若是本次求和大於最終結果,更新maxSum }; } return maxSum; }
算法複雜度:T(N)=O(NlgN)node
int MaxSubSeqSum(int arrays[], int left, int right) { int sum = 0; if (left == right) { if (arrays[left] > 0)return arrays[left]; else sum = 0; } else { int middle = (left + right) / 2; int leftSum = MaxSubSeqSum(arrays, left, middle); int rightSum = MaxSubSeqSum(arrays, middle + 1, right); int finalLeftSum = 0, thisLeftSum = 0; for (int i = left; i <=middle; i++) { thisLeftSum += arrays[i]; if (thisLeftSum > finalLeftSum)finalLeftSum = thisLeftSum; } int finalRightSum = 0, thisRightSum = 0; for (int j = middle + 1; j < right; j++) { thisRightSum += arrays[j]; if (thisRightSum > finalRightSum)finalRightSum = thisRightSum; } sum = finalLeftSum + finalRightSum; printf("left sum is %d,right sum is %d\n",finalLeftSum,finalRightSum); if (sum < leftSum)sum = leftSum; if (sum < rightSum)sum = rightSum; } return sum; }
int main() { int array[] ={1,6,-5,4,2,-3,6}; int result = MaxSubSeqSum(array,0,7); printf("result is %d\n", result); }
爲了方便觀察,咱們將每次左右兩邊求得的最大子序列最大和都打印出來面試
F:\ClionProject\DataStruct\cmake-build-debug\DataStruct.exe left sum is 1,right sum is 6 left sum is 0,right sum is 4 left sum is 7,right sum is 0 left sum is 2,right sum is 0 left sum is 6,right sum is 0 left sum is 0,right sum is 6 left sum is 6,right sum is 5 result is 11 Process finished with exit code 0
線性表是最基本、最簡單、也是最經常使用的一種數據結構。
線性表中數據元素之間的關係是一對一的關係,即除了第一個和最後一個數據元素以外,其它數據元素都是首尾相接的(注意,這句話只適用大部分線性表,而不是所有。好比,循環鏈表邏輯層次上也是一種線性表(存儲層次上屬於鏈式存儲),可是把最後一個數據元素的尾指針指向了首位結點)。算法
線性表的兩種存儲方式數組
typedef struct LinkedList{ int data[MAXSIZE];//存儲數組 int Last;//遊標指針 }List; List * MakeEmpty(){ List *Ptrl; Ptrl=(List *)malloc(sizeof(List)); Ptrl->Last=-1; return Ptrl; } /**T(n)=O(N)*/ int FindElement(int result,List* Ptrl){ int i=0; while(i<=Ptrl->Last&&Ptrl->data[i]!=result) i++; if(i>Ptrl->Last)return -1;//若是沒有找到返回-1 else return i; } void Insert(int result,int i,List *Ptrl){ int j; if(Ptrl->Last==MAXSIZE-1){ printf("表滿"); return; } if(i<1||i>Ptrl->Last+2){ printf("插入位置不合法"); return; } for(j=Ptrl->Last;j>=i-1;j--)//倒序移動(注意j>=i-1) Ptrl->data[j+1]=Ptrl->data[j]; Ptrl->data[i]=result;//插入數據 Ptrl->Last++;//Last指針++ return; } /*T(N)=O(N)*/ void DeleteElement(int i,List* Ptrl){ int j; if(i<1||i>Ptrl->Last+1){//判斷位置的合法性(注:鏈表下標是從1開始的) printf("第%d個元素不存在",i); return; } for(j=i;j<=Ptrl->Last;j++)//全部元素前移 Ptrl->data[j-1]=Ptrl->data[j]; Ptrl->Last--; return; }
typedef struct LinkedList { int data; struct LinkedList *next; } List; //求鏈表長度 int Length(List *Ptrl) { List *p = Ptrl; int j = 0; while (p) { p = p->next; j++; } return j; } //按序號查找 List *FindKth(int k, List *Ptrl) { List *p = Ptrl;//不改變頭節點,返回移動指針p int i = 1; while (p != NULL && i < k) { p = p->next; i++; } if (i == k)return p; else return NULL; } //按值查找 List *Find(int result, List *Ptrl) { List *p = Ptrl; while (p != NULL && p->data != result) p = p->next; return p; } //構造新的結點,申請空間 //找到鏈表的低i-1個結點 //修改指針插入結點 List *Insert(int result, int i, List *Ptrl) { List *p, *s; if (i == 1) {//判斷鏈表爲空的時候 s = (List *) malloc(sizeof(List)); s->data = result; s->next = Ptrl; return s; } p = FindKth(i - 1, Ptrl);//查找第i-1個節點 if (p == NULL) { printf("參數錯誤"); return NULL; } else { s = (List *) malloc(sizeof(List)); s->data = result; s->next = p->next; p->next = s; return Ptrl; } } List *Delete(int i, List *Ptrl) { List *p, *s; if (i == 1) {//檢查要刪除的是否是第一個結點 s = Ptrl;//s指向第一個結點 if (Ptrl != NULL)Ptrl = Ptrl->next;//從鏈表中刪除 else return NULL; free(s);//釋放空間 return Ptrl; } p = FindKth(i, Ptrl); if (p == NULL) {//後項前移 printf("輸入錯誤"); return NULL; } else if (p->next != NULL) { s=p->next; p->next = s->next; free(s);//清理無用空間 return Ptrl; } }
typedef struct{ int Data[MAXSIZE]; int Top; }Stack; void Push(Stack *stack,int value){ if(stack->Top==MAXSIZE-1){//數組有界 printf("堆棧滿"); }else{ stack->Data[++(stack->Top)]=value; return; } } int Pop(Stack *stack){ if(stack->Top==-1){//爲空檢查 printf("堆棧爲空"); return ERROR; } else return stack->Data[stack->Top--]; }
#define MAXSIZE 50 /*一個有界數組存儲兩個堆棧,若是數組有空間則執行入棧操做,(一個向右增加,一個向左增加) * */ typedef struct DStack{ int data[MAXSIZE]; int Top1; int Top2; }Stacks; void Push(Stacks *stacks,int value,int Tag){ if(stacks->Top2-stacks->Top1==1){ printf("堆棧滿");return; } if(Tag==1) stacks->data[++stacks->Top1]=value; else stacks->data[--stacks->Top2]=value; } int Pop(Stacks *stacks,int Tag){ if(Tag==1){ if(stacks->Top1==-1){ printf("堆棧1空"); return NULL; }else { return stacks->data[stacks->Top1--]; } }else{ if(stacks->Top2==MAXSIZE){ printf("堆棧2空"); return NULL; }else{ return stacks->data[stacks->Top2++]; } } } int main() { Stacks *stacks; stacks->Top1=-1; stacks->Top2=MAXSIZE;//初始化兩個堆棧頭指針 return 0; }
/*用單向鏈表表示棧時候,棧Top結點必定是鏈頭結點 * */ typedef struct Node{ int value; struct Node *next; }LinkedStack; LinkedStack * CreateLinkedStack(){ LinkedStack *stack; stack=(LinkedStack *)malloc(sizeof(LinkedStack)); stack->next=NULL; return stack; }; int isEmpty(LinkedStack *stack){//注意Top結點沒有值,只有一個單鏈表的頭指針 return (stack->next==NULL); } void Push(LinkedStack *stack,int value){ LinkedStack *insertElement; insertElement=malloc(sizeof(LinkedStack));//分配內存空間 insertElement->value=value;//插入的值賦值給結點 insertElement->next=stack->next;//將已存在鏈表連接到插入的結點 stack->next=insertElement;//改變Top結點 } int Pop(LinkedStack *stack){ int result; LinkedStack *popElement; if(isEmpty(stack)){ printf("鏈表爲空"); return ERROR; }else{ popElement=stack->next; result=popElement->value; stack->next=popElement->next; free(popElement);//記得釋放無用內存空間 return result; } }
中綴表達式如何轉換爲後綴表達式
從頭至尾讀取中綴表達式的每個對象數據結構
再比較新的棧頂運算符,直到改運算符大於棧頂運算符優先級爲止,而後壓棧app
堆棧用途:ide
#define MAXSIZE 50 typedef struct { int value[MAXSIZE]; int rear; int front; }Queue; Queue *CreateQueue(){ Queue *queue; queue=(Queue *)malloc(sizeof(Queue)); queue->front=0; queue->rear=0; return queue; } void AddQueue(Queue *queue,int value){ if((queue->rear+1)%MAXSIZE==queue->front){ printf("queue is full"); return; }else { queue->rear=(queue->rear+1)%MAXSIZE; queue->value[queue->rear] = value; } } int IsEmpty(Queue *queue){ if(queue->rear==queue->front)return 1; else return 0; } void OutQueue(Queue* queue,int *value){ if(IsEmpty(queue)){ printf("Queue is empty"); return; }else{ queue->front=(queue->front+1)%MAXSIZE; *value=queue->value[queue->front]; } }
typedef struct Node { int value; struct Node *next; } QNode; typedef struct { QNode *rear; QNode *front; } Queue; void InitQueue(Queue **queue) { QNode *p; p = (QNode *) malloc(sizeof(QNode)); p->next = NULL; (*queue)->front = p; (*queue)->rear = p; } void InQueue(Queue *queue, int value) { QNode *InElement; InElement = (QNode *) malloc(sizeof(QNode)); InElement->value = value; InElement->next = NULL; queue->rear->next = InElement; queue->rear = InElement; } int IsEmpty(Queue *queue) { if (queue->rear = queue->front)return 1; else return 0; } void OutQueue(Queue *queue, int *value) { QNode *OutElement; if (IsEmpty(queue)) { printf("queue is empty"); return; } else { OutElement = queue->front->next; queue->front->next=OutElement->next;//指針頭結點指向下一個結點(pspspspsps) *value=OutElement->value; free(OutElement); if(IsEmpty(queue)){//出隊列後若是隊列爲空則置爲空隊列 queue->front=queue->rear; } } }
每一個結點須要查找的次數恰好爲該結點所在的層數,查找成功時查找次數不會超過斷定樹的深度,n個結點的斷定樹的深度爲[LgN]+1函數
平均查找長度ASL(Average Search Length)
ASL=sum(層數*個數)/各層總個數n(n>=0)個結點構成的有限集合當n=0時稱爲空樹oop
對於任何一棵非空樹(n>0),它具有如下性質測試
樹的特色:
樹的一些基本術語:
兒子兄弟表示法能夠將全部的樹轉化爲二叉樹
特殊二叉樹:
二叉樹的特色
二叉樹的抽象數據類型定義
數據對象集:一個有窮的結點集合
若不爲空,則由根節點和其左、右二叉樹組成
操做集:判斷樹是否爲空,遍歷,建立二叉樹
經常使用的遍歷方法有:
先序遍歷(根左右),
中序遍歷(左根右),
後序遍歷(左右根),
層次遍歷(從上到下,從左到右)
在二叉樹中,咱們知道葉結點總數n0與有兩個兒子的結點總數n2之間的關係是:n0=n2+1.
那麼相似關係是否能夠推廣到m叉樹中?也就是,若是在m叉樹中,葉結點總數是n0,
有一個兒子的結點總數是n1,有2個兒子的結點總數是n2,有3個兒子的結點總數是n3,
那麼,ni之間存在什麼關係?
typedef struct BT{ int value; struct BT *leftchild; struct BT *rightchild; }BinTree; //二叉樹的每一個結點遍歷都會遇到三次,第一次遇到就打印的爲先序遍歷,第二次遇到就打印的爲中序遍歷,第三次遇到就打印的爲後序遍歷 //先序遍歷(遞歸遍歷) void PreOrderTraversal(BinTree *BT){ if(BT){ if(!BT->leftchild&&!BT->rightchild) printf("%d\n",BT->value); PreOrderTraversal(BT->leftchild); PreOrderTraversal(BT->rightchild); } } //中序遍歷(遞歸遍歷) void InOrderTraversal(BinTree *BT){ if(BT){ if(!BT->leftchild&&!BT->rightchild) InOrderTraversal(BT->leftchild); printf("%d\n",BT->value); InOrderTraversal(BT->rightchild); } } //後序遍歷(遞歸遍歷) void PostOrderTraversal(BinTree *BT){ if(BT){ if(!BT->leftchild&&!BT->rightchild) PostOrderTraversal(BT->leftchild); PostOrderTraversal(BT->rightchild); printf("%d\n",BT->value); } } //二叉樹遍歷的本質是將二維序列轉換爲一維序列 //使用隊列進行二叉樹的層級訪問(遍歷根節點,將左右兒子節點入隊列) void LevelOrderTraversal(BinTree BT){ Queue *queue; BinTree *T; queue=CreateQueue(); AddQueue(queue,BT); while(!IsEmptyQueue(queue)){ T=DeleteQueue(queue); printf("%d\n",T->value); if(T->leftchild)AddQueue(queue,T->leftchild); if(T->rightchild)AddQueue(queue,T->rightchild); } } //給定前中序遍歷結果或中後序遍歷結果能夠惟一肯定一棵二叉樹,給定先後序遍歷結果不能惟一肯定二叉樹 //非遞歸實現(中序遍歷) void InOrderTraversal(BinTree *BT){ BinTree *T=BT; LinkedStack *stack=CreateLinkedStack();//建立並初始化堆棧 while(T||!isEmpty(stack)){ while(T){//一直向左將沿途結點壓入堆棧 Push(stack,T); T=T->leftchild;//轉向左子樹 } if(!isEmpty(stack)){ T=Pop(stack);//結點彈出堆棧 printf("%5d",T->value);//打印結點 T=T->rightchild;//轉向右子樹 } } } //非遞歸實現(先序遍歷) void PreOrderTraversal(BinTree *BT){ BinTree *T=BT; LinkedStack *stack=CreateLinkedStack();//建立並初始化堆棧 while(T||!isEmpty(stack)){ while(T){//一直向左將沿途結點壓入堆棧 printf("%5d",T->value);//打印結點 Push(stack,T); T=T->leftchild;//轉向左子樹 } if(!isEmpty(stack)){ T=Pop(stack);//結點彈出堆棧 T=T->rightchild;//轉向右子樹 } } }
也稱二叉排序樹或二叉查找樹
二叉搜索樹條件
1.非空左子樹的全部鍵值小於其根節點的鍵值 2.非空右子樹的全部鍵值大於其根節點的鍵值 3.左,右子樹都是二叉搜索樹
//遞歸方式實現 Position Find(BinTree *binTree,int result){ if(!binTree)return NULL; if(result>binTree->value)return Find(binTree->rightchild,result); else if(result<binTree->value)return Find(binTree,result); else return binTree;//查找成功,返回結點地址(return尾遞歸) } //非遞歸方式實現 Position IterFind(BinTree *binTree,int value){ while(binTree){ if(result>binTree->value) binTree=binTree->rightchild; else if(result<binTree->value) binTree=binTree->leftchild; else return binTree; } return NULL; } //尋找最小值 Position FindMin(BinTree *binTree){ if(!binTree)return NULL; else if(!binTree->leftchild) return binTree; else return FindMin(binTree->leftchild); } //尋找最大值 Position FindMax(BinTree *binTree){ if(binTree){ while(binTree->rightchild) binTree=binTree->rightchild; } return binTree; } //結點插入 BinTree * Insert(BinTree *binTree, int value) { if(!binTree){ binTree=malloc(sizeof(BinTree)); binTree->value=value; binTree->leftchild=binTree->rightchild=NULL; }else{ if(value<binTree->value) binTree->leftchild=Insert(binTree->leftchild,value); else if(value>binTree->value) binTree->rightchild=Insert(binTree->rightchild,value); } return binTree; } //刪除結點 BinTree *Delete(BinTree *binTree,int value){ (Position)BinTree *Temp; if(!binTree)printf("要刪除的元素未找到"); //左子樹遞歸刪除 else if(value<binTree->value)binTree->leftchild=Delete(binTree,value); //右子樹遞歸刪除 else if(value>binTree->value)binTree->rightchild=Delete(binTree->rightchild,value); else //找到要刪除的結點 if(binTree->leftchild&&binTree->rightchild){//被刪除結點有左右量子子節點 Temp=FindMin(binTree->rightchild);//在右子樹中招最小的元素填充刪除結點 binTree->value=Temp->value; binTree->rightchild=Delete(binTree->rightchild,binTree->value); }else{//被刪除的結點有一個或無子結點 Temp=binTree; if(!binTree->leftchild)binTree=binTree->rightchild; else if(!binTree->rightchild)binTree=binTree->leftchild; free(Temp); } return binTree; }
(AVL樹)(AVL是提出平衡樹的學者名字首字母)
#define MaxData 10000 typedef struct HeapStruct{ int *value;//存儲對元素的數組 int length;//堆的當前元素個數 int capacity;//堆的最大容量 }Heap;
取出元素的前後順序是按照元素的優先權(關鍵字)大小,而不是元素進入隊列的前後順序
最大堆和最小堆都必須知足徹底二叉樹(切根節點最大或最小)最大堆的創建
創建最大堆:將已經存在的N個元素按最大堆的要求存放在要給一維數組中
方法二:在線性時間複雜度下創建最大堆
對由一樣n個整數構成的二叉搜索樹(查找樹)和最小堆:有如下結論
Heap * Create(int MaxSize){ Heap *heap=malloc(sizeof(Heap)); heap->value=malloc((MaxSize+1)*sizeof(int)); heap->length=0; heap->capacity=MaxSize; heap->value[0]=MaxData;//定義哨兵,便於操做 return heap; } void Insert(Heap *heap,int value){ int i; if(IsFull(heap)){ printf("最大堆已經滿了"); return; } i=++heap->length; for(;heap->value[i/2]<value;i/=2) heap->value[i]=heap->value[i/2]; heap->value[i]=value; } int DeleteMax(Heap *heap){ int parent,child; int maxValue,temp; if(IsEmpty(heap)){ printf("最大堆已空"); return 0; } maxValue=heap->value[1]; //用最大堆中最後一個元素從根節點開始過濾下層結點 temp=heap->value[heap->length--]; for(parent=1;parent*2<=heap->length;parent=child){ child=parent*2; //左兒子和右兒子節點比較取較大者 if((child!=heap->length)&&(heap->value[child]<heap->value[child+1])) child++; if(temp>=heap->value[child])break; else heap->value[parent]=heap->value[child]; } heap->value[parent]=temp; return maxValue; } int IsEmpty(Heap *heap){ return heap->length==0; } int IsFull(Heap *heap){ return heap->length==heap->capacity; } typedef struct TreeNode{ int weight; struct TreeNode *left,*right; }HuffmanTree;
查找效率,查找次數乘查找機率
帶權路徑長度(WPL):設二叉樹有n個葉子結點,每隔葉子結點帶有權值Wk,從根節點到每隔葉子結點的長度是Lk,則每隔葉子結點的帶全路徑長度之和WPL=(nEk=1)WkLk
最優二叉樹或哈夫曼樹:WPL最小的二叉樹
哈夫曼樹的特色
HuffmanTree的任意非葉結點的左右子樹交換後還是HuffmanTree
對於一組權值,可能有不一樣構的兩棵HuffmanTree
HuffmanTree *Huffman(Heap *heap){ //假設heap->length權值已經存在heap->value[]->weight裏面 int i;HuffmanTree *huffmanTree; BuildHeap(heap);//將heap->value[]按權值調整爲最小堆 for(i=1;i<heap->length;i++){ huffmanTree=malloc(sizeof(HuffmanTree));//創建新結點 huffmanTree->left=DeleteMin(heap);//從最小堆中刪除一個結點,做爲新huffmanTree的左子結點 huffmanTree->right=DeleteMin(heap);//從最小堆中刪除一個結點,做爲新huffmanTree的右子結點 huffmanTree->weight=huffmanTree->weight+huffmanTree->right->weight;//計算新// 權值 Insert(heap,huffmanTree); } huffmanTree=DeleteMin(heap); return huffmanTree; } /*二叉樹用於編碼 * 當被編碼字母所有在二叉樹的葉子結點的時候(即,編碼字母不會出如今有子節點的結點中)即可以保證字符編碼沒有二義性
偶然在一本書上看到這樣一道題以爲聽一意思的就拿來作了一下,題目是這樣設置的 **在已知一維數組A[m+n]中一次存放兩個線性表(a1,a2,a3,a4...am),(b1,b2,b3...bn),試寫出一個函數將兩個順序表位置互換,即由`(a,1,a2,a3,a4...am,b1,b2,b3...bn)`轉換成`(b1,b2,b3...bn,a,1,a2,a3,a4...am)`要求空間複雜度爲O(1)**想必這種題會常常出如今面試題目中吧,哈哈,扯遠了,如下是個人答案,水平有限,若有紕漏還望各位大神不吝賜教。 乍一看題目還挺麻煩的,兩個數組大小不同,原地逆置循環次數不容易控制,換個思路從新整理一下發現能夠用一種很巧妙的方法分三步實現 第一步:將字母序列逆置 第二部:將數字序列逆置 第三部:將數組總體逆置 **其中逆置函數以下:** 逆置函數須要兩個參數,分別爲須要逆置的數組起始位置[start]和終止位置[end];
public static void reverse(int start,int end){//逆置函數 char temp; while(start<end) { temp = array[start]; array[start++] = array[end]; array[end--] = temp; } }
tip:*char array[]={'A','B','C','D','E','F','G','H','1','2','3','4'}* 測試數組A[0-7],B[8-11] **測試結果以下:** ![image.png](http://upload-images.jianshu.io/upload_images/2480310-05c78f4d0acc3395.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/640) ### 完整代碼
public class Main {
public static char array[]={'A','B','C','D','E','F','G','H','1','2','3','4'}; public static void main(String[] args) { reverse(0,7);//逆置字母序列結果爲:HGFEDCBA1234 reverse(8,11);//逆置數字序列結果爲:HGFEDCBA4321 reverse(0,11);//總體逆置結果爲:1234ABCDEFG print(array); } public static void reverse(int start,int end){//逆置函數 char temp; while(start<end) { temp = array[start]; array[start++] = array[end]; array[end--] = temp; } } private static void print(char[] array) { for (int i = 0; i <array.length; i++) System.out.print(array[i]); System.out.println(); }
}
### N皇后問題
/**
*
public class EightQueen {
private int QUEEN_COUNT = 0;//represent the queen count private int[][] queenCount;//chess box matrix private int resultCount = 0;//solution number private int[] queenPlace;//mark the queen placed position /** * construct a EightQueen with a argument represent the number of queen * initial a empty chess box * 0 represent empty * 1 represent the area has been taken * recurse to call the putQueen method * the queenPlace array to mark the queen's taken area which uses to print * * */ public EightQueen(int n) { this.QUEEN_COUNT = n; this.resultCount = 0; this.queenCount = new int[QUEEN_COUNT][QUEEN_COUNT]; queenPlace = new int[QUEEN_COUNT]; putQueen(0); } /** * implement the putQueen function to recursion * use column index in outer loop and row index in inner loop with step increase * */ private void putQueen(int row) { for (int column = 0; column < QUEEN_COUNT; column++) {//loop for QUEEN_COUNT times if (queenCount[row][column] == 0) {//judge the condition /** * each row has one queen * mark the column and diagonal back diagonal(row has been scatter) * * */ for (int nextRow = row + 1; nextRow < QUEEN_COUNT; nextRow++) { queenCount[nextRow][column]++; if (column - nextRow + row >= 0) { queenCount[nextRow][column - nextRow + row]++; } if (column + nextRow - row < QUEEN_COUNT) { queenCount[nextRow][column + nextRow - row]++; } } queenPlace[row] = column;//place the queen with only column information if (row == QUEEN_COUNT - 1) printQueen(++resultCount);//recursion has completed else putQueen(row + 1);//recurse to call the putQueen function /** * * unmarked the column and diagonal back diagonal(row has been scatter) * * */ for (int rows = row + 1; rows < QUEEN_COUNT; rows++) { queenCount[rows][column]--; if (column - rows + row >= 0) { queenCount[rows][column - rows + row]--; } if (column + rows - row < QUEEN_COUNT) { queenCount[rows][column + rows - row]--; } } } } if (row == 0) System.out.println(QUEEN_COUNT + " queens has totally " + resultCount + "result."); } private void printQueen(int size) { System.out.println("********** "+size+" **********\n"); for (int i = 0; i < QUEEN_COUNT; i++) { for (int j = 0; j < QUEEN_COUNT; j++) { System.out.print(queenPlace[i] == j ? " # " : " - "); } System.out.println(); } }
}
### 優先隊列
/**
public class PriorityQueue{
private static final int MAX_SIZE_OF_PRIORITY_QUEUE=100; private int[] initialArray; /** * initial priority queue with a exist array which can't be null * */ public PriorityQueue(int[] initialElement) { if(initialElement==null)return; if(initialElement.length==0)return; initialArray=new int[MAX_SIZE_OF_PRIORITY_QUEUE]; initialArray[0]=initialElement.length; for(int i=0;i<initialElement.length;i++)initialArray[i+1]=initialElement[i]; System.out.println(initialArray[0]); for (int i = initialArray[0]; i >0 ; i--)reBuildHeap(i); } /** * rebuild array according to the value of each node * maximum-top heap * index represents the index of a node which should be rebuild(include it's children node) * * simple: * 1 * 2 3 * 4 5 6 7 * * */ private void reBuildHeap(int index){ System.out.println("execute rebuild function to rebuild a maximum-top heap with one loop"); int leftChildIndex=index*2; int rightChildIndex=leftChildIndex+1; int length=initialArray[0]; int biggerValueIndex=-1; if(leftChildIndex>length&&rightChildIndex>length){ System.out.println("no left child"); return; } if(leftChildIndex<=length&&rightChildIndex>length){ System.out.println("only left child"); biggerValueIndex=leftChildIndex; } if(leftChildIndex>length&&rightChildIndex<=length){ System.out.println("only right child"); biggerValueIndex=rightChildIndex; } if(leftChildIndex<=length&&rightChildIndex<=length){ System.out.println("both children"); biggerValueIndex=initialArray[leftChildIndex]>initialArray[rightChildIndex]?leftChildIndex:rightChildIndex; } if(initialArray[index]>initialArray[biggerValueIndex]){ System.out.println("unnecessary to swap!"); return; }else{ int temp=initialArray[index]; initialArray[index]=initialArray[biggerValueIndex]; initialArray[biggerValueIndex]=temp; this.reBuildHeap(biggerValueIndex); } } public int getLength() { return initialArray[0]; } /** * get top priority value of heap * the first element of array * */ public int priority(){ return initialArray[1]; } /** * length++ * add element to the tail of array * rebuild the heap to regular priority heap * */ public void insert(int element){ initialArray[0]++; initialArray[initialArray[0]]=element; for(int i=initialArray[0];i>=1;i=i/2){ reBuildHeap(i); } } /** * length-- * swap the first element and last element * delete last value * rebuild the heap * */ public int deletePriority(){ if(initialArray[0]<=0)return -1; int maxValue=initialArray[1]; initialArray[1]=initialArray[initialArray[0]]; initialArray[0]--; for(int i=initialArray[0];i>=1;i=i/2){ reBuildHeap(i); } return maxValue; } /** * print the structure of priority heap * */ @Override public String toString() { StringBuilder builder=new StringBuilder("{"); for (int i = 1; i <= initialArray[0]; i++) { if(i!=1)builder.append(","); builder.append(initialArray[i]); } builder.append("}"); return builder.toString(); }
}