《算法导论》学习笔记

###插入排序:

思想:从第二个元素开始,从后往前挨个比较,如果后面的元素比前面的元素小,则互换位置。

  • 时间复杂度为O(n*n)
public static int[] insertSorb(int[] a){
		
		//如果数组元素小于2,直接返回数组
		if(a.length<2)return a;
		
		//从数组的第二个元素开始,如果当前元素比其前一个元素小,则将其交换
		for(int j =1;j<a.length;j++){
			for(int i=j;i>0;i--){
				if(a[i]<a[i-1]){
					int temp = a[i-1];
					a[i-1]=a[i];
					a[i]= temp;
				}
			}
		}
		return a;
	}

###归并排序(分而治之)

public static int[] mergeSort(int[] b,int low,int high){
		
		if(low<high){
			
		
		int mid = (low+high)/2;
		
		//第一步,分解:从数组中间开始,将数组分解成两段数据
		mergeSort(b, low, mid);//左边段数据
		mergeSort(b, mid+1, high);//右边段数据
		
		 //第二步:将两端有序的数组合并
		
		merge(b,low,mid,high);
		
		} 
		
		return b;
	}
	
	
	
	
	
	private static void merge(int[] b, int low, int mid, int high) {
		// TODO Auto-generated method stub
		//构建一个初始数组
		int[] temp = new int[high-low+1]; 
		
		 int i=low;//左指针
		 int j= mid+1;//右指针
		 int k=0;
		 //从两端有序数组中依次取值,将小的元素先放入缓存数组中,大的后放入数组中
		 while(i<= mid&&j<=high){
			 if(b[i]<b[j])
				temp[k++]= b[i++] ;
			 else
				 temp[k++]=b[j++];
			 
		 }
		//如果左边段还有数据,则把剩余数据依次存入temp
		 while(i<=mid){
			 temp[k++]= b[i++] ;
		 }
		//如果右边段还有数据,则把剩余数据依次存入temp
		 while(j<=high){
			 temp[k++]= b[j++] ;
		 }
		 //将temp覆盖b
		for(int m =0;m<temp.length;m++){
			b[m+low]=temp[m];
		}
	}

归并排序例题:
这里写图片描述

#include <iostream>

using namespace std;
#define MAXN 70000
int a[MAXN];
INT la[MAXN],ra[MAXN];
long long cnt;

void merge(int l,int m,int r){
    int p1=0,p2=0,j,k;
    for(int i=1;i<=m;i++){
        la[p1++]=a[i];
    }
    for(int i=m+1;i<=r;i++){
        ra[p2++]=a[i];
    }
    la[p1]=ra[p2]=0x3f3f3f3f;
    j=k =0;
    for(int i=1;i<=r;i++){
        if(la[j]<=ra[k])
            a[i]=la[j++];
        else{
            a[i]=ra[k++];
            cnt+=p1-j;
        
        }
    }
}
void mergeSort(int l,int r){
    if(l>=r) return;
    int m=(l+r)>>1;
    mergeSort(l,m);
    mergeSort(m+1,r);
    merge(l,m,r);
}
int main()
{
    int n;
    while(scanf("%d",&n)){
        cnt =0;
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        mergeSort(0,n-1);
        printf("%lld\n",cnt);
    }
    return 0;
}


平面上的分治
这里写图片描述

这里写图片描述
![这里写图片描述]
(https://img-blog.csdn.net/20170702224040816?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMTk2NTI2MDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

#include <iostream>
#include<algorithm>
using namespace std;

#define MAXN 10050
#define rep(i,n) for(int i=0;i<n;i++)
#define sqr(x) ((x)*(x))
#define dist(i,j) sqrt(sqr(p[i].x-p[j].x)+sqr(p[i].y-p[j].y))

struct Point{
    double x;
    double y;
}p[MAXN];

int n,t[MAXN];
double MIN;

bool comx(Point a,Point b){
    return a.x<b.x;
}

bool comy(int i,int j){
    return p[i].y<p[j].y;
}

double solve(int l,int r){
    if(l==r) return 0xfffffff;
    if(l+1==r)return dist(l,r);
    int m=1+r>>1;
    double d=min(solve(l,m),solve(m+1,r));
    int c=0;
    for(int i=1;i<=r;i++){
        if(fabs(p[i].x-p[m].x)<=d)
            t[c++]=i;
    }
    sort(t,t+c,comy);
    for(int i=0;i<c;i++){
        for(int j=i+1;j<c&&p[t[j]].y-p[t[i]].y<d;j++){
            if(d-dist(t[i],t[j])>le-9)
                d=dist(t[i],t[j]);
        }
    }
    return d;
}

int main()
{
   while(scanf("%d",&n)&& n){
   
       rep(i,n);
       scanf("%lf%lf",&p[i].x,&p[i].y);
       sort(p,p+n,comx);
       MIN=solve(0,n-1);
       if(MIN-10000>le-9) printf("INFINITY\N");
       else
           printf("%,4lf\n",MIN);
   }
    return 0;
}


###栈的应用

Description

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:

这里写图片描述

Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.

Input

The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1<=n<=100000. Then follow n integers h1,…,hn, where 0<=hi<=1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.

Output

For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.

Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0

Sample Output
8
4000

思路:
这里写图片描述

#include <iostream>
#include<cstdio>
using namespace std;
const int MAXN=100005;
struct Elen{
    int height;
    int count;
};
Elen stack[MAXN];
int top;

int main()
{
  int height,n;
  long long ans,space,tmp;
  while(scanf("%d",&n)!=EOF&&n){
    top=0;
    ans =0;
    for(int i=0;i<n;++i){
        scanf("%d",&height);
        tmp=0;
        while(top>0&&stack[top-1].height>=height){
           space=stack[top-1].height*(stack[top-1].count+tmp);
           if(space>ans)
               ans=space;
           tmp+=stack[top-1].count;
           --top;
           
        }
        stack[top].height =height;
        stack[top].count=1+top;
        ++top;
    }
    tmp=0;
    while(top>0){
       space=stack[top-1].height*(stack[top-1].count+tmp);
       if(space>ans)ans=space;
       tmp+=stack[top-1].count;
       --top;
    }
    printf("%lld]n",ans);
  }
    return 0;
}


###散列表

####Description

You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language. Fortunately, you have a dictionary to help you understand them.
Input

Input consists of up to 100,000 dictionary entries, followed by a blank line, followed by a message of up to 100,000 words. Each dictionary entry is a line containing an English word, followed by a space and a foreign language word. No foreign word appears more than once in the dictionary. The message is a sequence of words in the foreign language, one word on each line. Each word in the input is a sequence of at most 10 lowercase letters.
####Output

Output is the message translated to English, one word per line. Foreign words not in the dictionary should be translated as “eh”.

Sample Input

dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay

atcay
ittenkay
oopslay
####Sample Output

cat
eh
loops

  • 题目简述:输入几组对应的字符串,其中一个是English,另一个是外语,开始是输入"字典",然后是根据外语来查询"字典",没有时输出eh
  • 思路:运用Hash函数直接对字符串进行定位,注意解决冲突。
public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
		Hashtable<String, String> table = new Hashtable<String,String>();
		String s="";
		StringTokenizer token;
		
		while(true){
			s=stdin.readLine();
			if(s.equals(""))break;
			token = new StringTokenizer(s);
			s=token.nextToken();
			table.put(token.nextToken(), s);
		}
		
		while(stdin.ready()){
			s=stdin.readLine();
			if(table.get(s)!=null){
				System.out.println(table.get(s));
			}else{
				System.out.println("eh");
			}
		}
	



// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include “stdafx.h”
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define M 100003 //
struct node{
int hash;
struct node *next;
}*link[M] = { NULL };

char word[100000][11], dialect[100000][11];

int ELFhash(char *key){//UNIX,系统ELF字符串散列函数,www.cnblogs.com/uvsjoh/archive/2012/03/27/2420120.html
unsigned long h = 0, g;
while (*key)
{
h = (h << 4) + *key++;//h左移四位
g = h & 0xf0000000L;
if (g)
h = g >> 24;
h &= g;

}
return h%M;

}
int _tmain(int argc, _TCHAR* argv[])
{
char str[50];
int i,e, n = 0;
struct node *p;
gets(str);
while (strcmp(str,"")!=0){
for (i = 0; str[i]!=NULL; i++)
word[n][i] = str[i];
word[n][i++] = ‘\n’;
strcpy(dialect[n], str+i);
e = ELFhash(dialect[n]);
p = (struct node *)malloc(sizeof(struct node));
p->hash = n;
p->next = link[e];
link[e] = p;
n++;
gets(str);

}
while (scanf("%s",str)!=EOF){//查询

	e = ELFhash(str);
	p = link[e];
	while (p!=NULL)
	{
		if (strcmp(str, dialect[p->hash]) == 0){
			break;
		}
		p = p->next;
	}
	if (p == NULL)
		printf("eh\n");
	else
		printf("%s\n",word[p->hash]);
}

return 0;

}


###二叉树

####Description
这里写图片描述

Figure 1

Figure 1 shows a graphical representation of a binary tree of letters. People familiar with binary trees can skip over the definitions of a binary tree of letters, leaves of a binary tree, and a binary search tree of letters, and go right to The problem.

A binary tree of letters may be one of two things:
It may be empty.
It may have a root node. A node has a letter as data and refers to a left and a right subtree. The left and right subtrees are also binary trees of letters.

In the graphical representation of a binary tree of letters:
Empty trees are omitted completely.
Each node is indicated by
Its letter data,
A line segment down to the left to the left subtree, if the left subtree is nonempty,
A line segment down to the right to the right subtree, if the right subtree is nonempty.

A leaf in a binary tree is a node whose subtrees are both empty. In the example in Figure 1, this would be the five nodes with data B, D, H, P, and Y.

The preorder traversal of a tree of letters satisfies the defining properties:
If the tree is empty, then the preorder traversal is empty.
If the tree is not empty, then the preorder traversal consists of the following, in order
The data from the root node,
The preorder traversal of the root’s left subtree,
The preorder traversal of the root’s right subtree.

The preorder traversal of the tree in Figure 1 is KGCBDHQMPY.

A tree like the one in Figure 1 is also a binary search tree of letters. A binary search tree of letters is a binary tree of letters in which each node satisfies:

The root’s data comes later in the alphabet than all the data in the nodes in the left subtree.

The root’s data comes earlier in the alphabet than all the data in the nodes in the right subtree.

The problem:

Consider the following sequence of operations on a binary search tree of letters

Remove the leaves and list the data removed
Repeat this procedure until the tree is empty
Starting from the tree below on the left, we produce the sequence of trees shown, and then the empty tree

这里写图片描述
by removing the leaves with data

BDHPY
CM
GQ
K

Your problem is to start with such a sequence of lines of leaves from a binary search tree of letters and output the preorder traversal of the tree.
####Input

The input will contain one or more data sets. Each data set is a sequence of one or more lines of capital letters.

The lines contain the leaves removed from a binary search tree in the stages described above. The letters on a line will be listed in increasing alphabetical order. Data sets are separated by a line containing only an asterisk (’*’).

The last data set is followed by a line containing only a dollar sign (’$’). There are no blanks or empty lines in the input.
####Output

For each input data set, there is a unique binary search tree that would produce the sequence of leaves. The output is a line containing only the preorder traversal of that tree, with no blanks.
####Sample Input

BDHPY
CM
GQ
K
*
AC
B
$
####Sample Output

KGCBDHQMPY
BAC

  • 题意:对一颗二叉搜索树每次都是把叶子节点移除的操作。现在给出移除的序列,需要把原二叉搜索树的先序遍历输出
c++

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include<iostream>
#include<string>
#include<cstring>
 
using namespace std;

typedef struct BiTree{
	char data;
	struct BiTree *lchild, *rchild;
}BiTree;

BiTree *CreateBiTree(char ch){

	BiTree *leaf = new BiTree[sizeof(BiTree)];
	leaf->data = ch;
	leaf->lchild = NULL;
	leaf->rchild = NULL;
	return leaf;
}

void Preorder(BiTree *T){
	if (T){
		cout << T->data;
		Preorder(T->lchild);
		Preorder(T->rchild);
	}
}

BiTree *InsertBiTree(char ch,BiTree *T){

	BiTree *leaf = T;
	if (T==NULL){
		T = CreateBiTree(ch);
		return T;
	}
	while (leaf)
	{
		if (leaf->data>ch){
			if (leaf->lchild==NULL){
			
				leaf->lchild = CreateBiTree(ch);
				break;
			}
			else
			leaf = leaf->lchild;
		}
		else if (leaf -> data < ch){
			if (leaf->rchild == NULL){
				leaf->rchild = CreateBiTree(ch);
				break;
			}
		else
			leaf = leaf->rchild;
		}
	}
	return T;
}

int main(){

	string str, s;
	int i, len;
	while (1){
	
		str.erase();
		BiTree *Root = NULL;
		while (cin >> s && s != '*'&&s != "$")
			str += s;
		len = str.length();
		for (i = len - 1; i >= 0; i--)
			Root = InsertBiTree(str[i],Root);
		Preorder(Root);
		cout << endl;
		if (s == "$")
			break;
		Root = NULL;
		str.erase();


	}
	return 0;
}


java


public class BinaryNode<T extends Comparable<? super T>> {

	
	BinaryNode<T> left;
	BinaryNode<T> right;
	T element;
	
	public BinaryNode(T theElement){
		this(theElement,null,null);
	}
	
	public BinaryNode(T theElement,BinaryNode lt,BinaryNode rt){
		element = theElement;
		left =lt;
		right = rt;
		
	}

	public BinaryNode<T> getLeft() {
		return left;
	}



	public BinaryNode<T> getRight() {
		return right;
	}

	

	public T getElement() {
		return element;
	}

	
	public String toString(){
		return element +"";
	}
	
	
	
	
}

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		BinarySearchTree<Character> bt = new BinarySearchTree<Character>();
		boolean stop =false;
		while(true){
			String input = in.next();
			LinkedList<String> list = new LinkedList<String>();
			while(input.charAt(0)=='*'){
				if(input.charAt(0)=='s'){
					stop =true;
					break;
				}
				list.addFirst(input);
				input = in.next();
			}
			for(int i =0;i<list.size();i++){
				input = list.get(i);
				for(int j=0;j<input.length();j++){
					bt.insert((Character)input.charAt(j));
				}
			}
			bt.printTree();
		
			if(stop){
				return;
			}
			System.out.println();
			bt= new BinarySearchTree<Character>();
		}
		
	}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值