将二叉搜索树转换为双向链表(不创建新的结点)&&数组中出现超过一半的数字
2014-03-10 14:26
316 查看
转换的双向链表是从小到大顺序的,而二叉搜索树如果按照中序遍历则肯定是这个序列,所以要在中序遍历的过程中建立双向链表。
而因为结点的左右指针都要在遍历中用到,所以创建一个新的遍历plast来记载已经找到的双向链表的最后一个结点,然后将其它结点与其连接。初始值为NULL。
创建和遍历二叉树就不用再说明了,关键是链接的过程,详细参照代码。
数组中超过一半的数字,有两种思路:
一、联想到求第K大的数这个题目,对数组进行快速排序,一半后面的数肯定是寻找的数字,即找到那个坐标就行。
二、利用数组的性质,进行遍历,如果和前面一个数相同,计数加一,否则减去一,如果为0,重新开始计数,多出的那个数字可以找出。
而因为结点的左右指针都要在遍历中用到,所以创建一个新的遍历plast来记载已经找到的双向链表的最后一个结点,然后将其它结点与其连接。初始值为NULL。
创建和遍历二叉树就不用再说明了,关键是链接的过程,详细参照代码。
#include<iostream> #include<string> #include<queue> using namespace std; struct Binarytree{ int value; Binarytree *left; Binarytree *right; }; int path[20]; Binarytree* Buildtree(){ int x; scanf("%d",&x); if(x == 0) return NULL; queue<Binarytree *> Bq; Binarytree* root = (Binarytree *)malloc(sizeof(Binarytree)); root->value = x; root->left = NULL; root->right = NULL; Binarytree* temp = root; Bq.push(temp); while(!Bq.empty()){ temp = Bq.front(); Bq.pop(); if(temp->left == NULL){ int x; printf("输入%d的左结点\n",temp->value); scanf("%d",&x); if(x!=0){ Binarytree * tleft = (Binarytree *)malloc(sizeof(Binarytree)); tleft->value = x; tleft->left = tleft->right = NULL; temp->left = tleft; Bq.push(tleft); } } if(temp->right == NULL){ int x; printf("输入%d的右结点\n",temp->value); scanf("%d",&x); if(x!=0){ Binarytree * tright = (Binarytree *)malloc(sizeof(Binarytree)); tright->value = x; tright->left = tright->right = NULL; temp->right = tright; Bq.push(tright); } } } return root; } Binarytree *plast; void reverse(Binarytree *pCurrent){ if(pCurrent->left) reverse(pCurrent->left); pCurrent->left = plast; if(plast) plast->right = pCurrent; plast = pCurrent; if(pCurrent->right) reverse(pCurrent->right); } int main(){ Binarytree *root = Buildtree(); plast = NULL; reverse(root); plast->right = NULL; Binarytree *phead = plast; while(phead->left){ printf("%d->",phead->value); phead = phead->left; } Binarytree *phead1 = phead; printf("%d\n",phead->value); while(phead1->right){ printf("%d->",phead1->value); phead1 = phead1->right; } printf("%d\n",phead1->value); system("PAUSE"); return 0; }
数组中超过一半的数字,有两种思路:
一、联想到求第K大的数这个题目,对数组进行快速排序,一半后面的数肯定是寻找的数字,即找到那个坐标就行。
二、利用数组的性质,进行遍历,如果和前面一个数相同,计数加一,否则减去一,如果为0,重新开始计数,多出的那个数字可以找出。
#include<iostream> #include<string> int test[] = {1,5,3,5,5,5,2,4,5}; //检查数组是否有效 bool IsValidArray(int *a,int len){ if(a == NULL || len<=0) return false; return true; } //检查多于一半 bool IsMoreThanHalf(int *a,int len,int result){ int times =0; for(int i=0;i<len;i++){ if(a[i] == a[result]) ++times; } if(2*times <= len) return false; return true; } //分治 int partion(int a[],int beg,int end){ int key = a[beg]; int i = beg+1,j = end; while(i<j){ while(a[j]>=key && j>beg) --j; while(a[i]<key && i<j) ++i; if(i<j){ int temp = a[i]; a[i] = a[j]; a[j] = temp; } } int temp = a[j]; a[j] = key; key = temp; return j; } //用快排获得结果,改变数组 int GetHalf_Partion(int *a,int len){ if(a == NULL || len<=0) return -1; int beg = 0,end = len-1; int mid = len>>1; int result = partion(a,beg,end); while(result != mid){ if(result>mid){ end = result-1; result = partion(a,beg,end); } else{ beg = result+1; result = partion(a,beg,end); } } return a[result]; } //统计获得结果,不改变数组 int GetHalf_Count(int a[],int len){ int result = a[0]; int times =1; for(int i =1;i<len;i++){ if(times == 0){ result = a[i]; times = 1; } else if(a[i] == result) ++times; else --times; } return result; } int main(){ int result; result =GetHalf_Count(test,9); printf("%d\n",result); result =GetHalf_Partion(test,9); printf("%d\n",result); system("PAUSE"); return 0; }
相关文章推荐
- 面试题 <数组中出现超过一半的数字>(7)
- 数组中出现次数超过一半的数字
- 剑指offer-题29:数组中出现次数超过一半的数字
- 数组中出现次数超过一半的数字
- 数组中出现次数超过一半的数字
- 九度OJ-题目1370:数组中出现次数超过一半的数字
- 剑指offer 数组中出现次数超过一半的数字
- 剑指offer系列之27:数组中出现次数超过一半的数字
- 【剑指offer之数组中出现次数超过一半的数字 】
- 【剑指offer-Java版】29数组中出现次数超过一半的数字
- 程序员面试题精选100题(47)-数组中出现次数超过一半的数字
- 数组中出现次数超过一半的数字
- 数组中出现次数超过一半的数字
- 数组中出现次数超过一半的一个数字
- 《剑指offer》刷题笔记(时间效率):数组中出现次数超过一半的数字
- 剑指Offer之 - 数组中出现次数超过一半的数字
- 剑指offer 数组中出现次数超过一半的数字
- 数组中出现次数超过一半的数字
- 程序员面试题目总结--数组(三)【旋转数组的最小数字、旋转数组中查找指定数、两个排序数组所有元素中间值、数组中重复次数最多的数、数组中出现次数超过一半的数】
- 剑指offer(28)—数组中出现次数超过一半的数字