目录
二分查找
public int findnum(vector<int> arr,int target){
int left,right,mid;
left = 0;
right = arr.size()-1;//**size-1
while(left <= right){//有等于
mid = left + (right-left)/2;//写在内部
if(target < arr[mid]){
right = mid-1;//-1
}
else if(target > arr[mid]){
left = mid+1;//+1
}
else if(target==arr[mid]){
return mid;
}
}
return -1;//-1别忘
}
直接插入排序
稳定
void InsertionSort(int *a, int len)
{
for (int i=1; i<len; i++)
{
int key = a[i];//现在所在元素
int j = i-1;//之前的元素
while (j>=0 && a[j]>key)//现在的元素小于之前的元素
{
a[j+1] = a[j];//之前的元素往后挪
j--;
}
a[j+1] = key;//放现在的元素
}
}
冒泡排序
void bubbleSort(int a[], int n)
{
int i,j;
for(i = 0; i<n - 1; i++){//**n-1趟冒泡
for(j = 0; j<n - 1 - i; j++){//**n-1-j,前面的冒泡
if(a[j] > a[j+1]) {
swap(a[j], a[j+1]);
}
}
}
}
快速排序
不稳定
public void quick_sort(int left,int right,vector<int> arr){
//left right开始排序的下标位置
if(left>=right){//星星
return;
}
int i,j,base;
i = left;
j = right;
base = arr[left];
while(i < j){
if(base<=arr[j]&&i<j){
j--;
}
if(base>=arr[i]&&i<j){
i++;
}
swap(arr[i],arr[j]);
}
//星星
arr[left] = arr[i];
arr[i] = base;
quick_sort(left,i-1,arr);
quick_sort(j+1,right,arr);
}
选择排序
不稳定
void select_sort(int a[], int n)
{
int index;
int i,j;
for (i = 0; i < n - 1; i++)
{
index = i;
for (j = i + 1; j < n; j++)
{
if (a[index] < a[j])
{
index = j;
}
}
swap(a[index], a[i]);
}
}
堆排序
// 递归方式构建大根堆(len是arr的长度,index是第一个非叶子节点的下标)
void adjust(vector<int> &arr, int len, int index)
{
int left = 2*index + 1; // index的左子节点
int right = 2*index + 2;// index的右子节点
//找子树的最大节点下标
int maxIdx = index;
if(left<len && arr[left] > arr[maxIdx])
maxIdx = left;
if(right<len && arr[right] > arr[maxIdx])
maxIdx = right;
//最大节点不是父节点则交换位置
if(maxIdx != index)
{
swap(arr[maxIdx], arr[index]);
adjust(arr, len, maxIdx);
}
}
// 堆排序
void heapSort(vector<int> &arr, int size)
{
// 构建大根堆(从最后一个非叶子节点向上)
for(int i=size/2 - 1; i >= 0; i--)
{
adjust(arr, size, i);
}
// 调整大根堆
for(int i = size - 1; i >= 1; i--)
{
swap(arr[0], arr[i]); // 将当前最大的放置到数组末尾
adjust(arr, i, 0); // 将未完成排序的部分继续进行堆排序
}
}
二叉树深度优先遍历dfs
前序遍历
//递归实现:根左右
void preOrder1(BinTree *root)
{
if (root != NULL)
{
cout<<root->data<<endl;
preOrder1(root->lchild);
preOrder1(root->rchild);
}
}
//非递归实现
/*注意,如前所述,我们将二叉树的每一个结点都看作根结点。因此,从整个二叉树的根结点root出发,一路向左,遇到的每一个结点都立即访问(它是根,同时也是其父亲的左子树的根,所以这个过程访问了“根和左”)并入栈,直到不能再左,转向右(这个“右”上哪找呢?当然是父亲的右儿子。父亲去哪里找呢?当然是栈里),将这个右儿子当成新的根结点重复上述过程,直到栈为空且当前根结点也为空。*/
void preOrder2(BinTree *root)
{
stack<BinTree *> s;
BinTree *p=root;
while (p!=NULL || !s.empty())
{
//一路向左
while (p!=NULL)
{
cout<<p->data<<endl; //访问根结点
s.push(p);
p=p->lchild;
}
//当不能再左时,开始向右
if (!s.empty())
{
p=s.top();//从栈里面取出根结点
s.pop();
p=p->rchild; //作为新的根结点
}
}
}
中序遍历
//递归实现:左根右
void inOrder1(BinTree *root)
{
if (root != NULL)
{
inOrder1(root->lchild);
cout<<root->data<<endl;
inOrder1(root->rchild);
}
}
//非递归实现
/*与前序遍历类似,但是,根结点进栈时不访问(否则就成了前序遍历),根结点弹栈时才访问(左根右)。*/
void inOrder2(BinTree *root)
{
stack<BinTree *> s;
BinTree *p=root;
while (p!=NULL || !s.empty())
{
//一路向左
while (p!=NULL)
{
s.push(p);
p=p->lchild;
}
//当不能再左时,访问根结点,向右
if (!s.empty())
{
p=s.top();
cout<<p->data<<endl; //在中间访问根结点
s.pop();
p=p->rchild;
}
}
}
后序遍历
//递归实现:左右根
void postOrder1(BinTree *root)
{
if (root != NULL)
{
postOrder1(root->lchild);
postOrder1(root->rchild);
cout<<p->data<<endl;
}
}
//非递归实现
/*对任一结点p,边一路向左边进栈,直到其左儿子为空,这时,各个根结点在栈里存放。然后依次出栈,但是此时还不能访问(否则就是中序遍历了),出栈之后以当前根节点的右儿子设置为新的根节点,重复前述过程;直到当前根节点第二次出栈(说明它的左右儿子都已被访问),然后访问此根结点(左右根)。*/
typedef struct _poNode
{
BinTree *btnode;
bool isFirst;
} poNode;
void postOrder2(BinTree *root)
{
stack<poNode *> s;
BinTree *p=root;
poNode *temp;
while (p!=NULL || !s.empty())
{
//一路向左直到不能再左
while (p!=NULL)
{
temp = (poNode *)malloc(sizeof(poNode));
temp->btnode = p;
temp->isFirst = True; //第一次进栈标记
s.push(temp);
p=p->lchild;
}
if (!s.empty())
{
temp = s.top(); //此时还不能访问,否则就是中序遍历了
s.pop();
//如果是第一次进栈,那还需要再进栈一次,之后以它的右儿子为新的根结点
if (temp->isFirst == true)
{
temp->isFirst = false;
s.push(temp);
p = temp->btnode->rchild;
}
else
{
cout<<temp->btnode->data<<endl; //后序访问根结点
p = NULL; //不要忘了这一句,因为访问过根结点之后应该直接弹栈考察上一个父结点
}
}
}
}
二叉树的层次遍历
public static void treeBFS(TreeNode root) {
//如果为空直接返回
if (root == null)
return;
//队列
Queue<TreeNode> queue = new LinkedList<>();
//首先把根节点加入到队列中
queue.add(root);
//如果队列不为空就继续循环
while (!queue.isEmpty()) {
//poll方法相当于移除队列头部的元素
TreeNode node = queue.poll();
//打印当前节点
System.out.println(node.val);
//如果当前节点的左子树不为空,就把左子树
//节点加入到队列中
if (node.left != null)
queue.add(node.left);
//如果当前节点的右子树不为空,就把右子树
//节点加入到队列中
if (node.right != null)
queue.add(node.right);
}
}
转换进制
// 将10进制下的数字转为n进制
int toNBase(int num, int base){
int res=0, factor=1;
while(num){
res += factor*(num%base);
num /= base;
factor *= 10;
}
return res;
}
// 将n进制下的数字转为10进制
int to10Base(int num,int base) {
int res=0,factor=1;
while(num) {
res += factor*(num%10);
num /= 10;
factor *= base;
}
return res;
}