算法笔试题总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、递归和分制策略
汉诺塔递归实现:
Void hannoi(int n,char x,char y,char z)
{
if (n ==1)
move(x,1,z);//printf(“%i Move disk %i from %c to %c \n”,++c,n,x,z)
//将编号1从x移到z
else{
hanoi(n-1, x,z,y);//将x上编号1至n-1的移到y,z做辅助
move(x,n,z);// 将编号n从x移到z
hanoi(n-1, y,x,z);// 将y上编号1至n-1的移到z,x做辅助
}
}
递归小结
优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。

缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。

解决方法:在递归算法中消除递归调用,使其转化为非递归算法。

1.采用一个用户定义的栈来模拟系统的递归调用工作栈。

该方法通用性强,但本质上还是递归,只不过人工做了
本来由编译器做的事情,优化效果不明显。

2.用递推来实现递归函数。

3.通过Cooper变换、反演变换能将一些递归转化为尾递归,从而迭代求出结果。

后两种方法在时空复杂度上均有较大改善,但其适用范围有限。

排序总结
直接插入排序:
void insertSort(listtp & r)
{ for(i=2; i<=n; i++)
{ r[0]=r[i]; /* 设置监视哨*/
j=i-1; k=r[i].key;
while(j>0&&r[j].key>k)/* 大值的记录后移*/ { r[j+1]=r[j]; j--; }
r[j+1]=r[0]; /*插入位置*/
}
} /* straisort */
希尔排序:将整个序列划分成若干子序列,分别进行直接插入排序。

void ShellSort(SeqList R,int dlta[],int t)
{
For(k=0;k<t;k++)
ShellInsert(R,dlta[k]); //一趟增量为dlta[k]的Shell插入排序
} //ShellSort
{ for(i=dk+1; i<=n; i++)
{ r[0]=r[i]; /* 设置监视哨*/
j=i-dk; k=r[i].key;
while( r[j].key>k)/* 大值的记录后移*/
{ r[j+dk]=r[j]; j-=dk; }
r[j+dk]=r[0]; /*插入位置*/
}
} /* straisort */
冒泡排序:
void buble_sort(listtp r)
{ for (i=1; i<=n-1; i++) /* 共计n-1趟 */
for (j=1; j<=n-i ; j++)
if (r[j].key>r[j+1].key)
{ x=r[j]; r[j]=r[j+1] r[j+1]=x;} } /* bubble_sort */
快速排序:在快速排序中,记录的比较和交换是从两端向中间进行的,关键字较大的记录一次就能交换到后面单元,关键字较小的记录一次就能交换到前面单元,记录每
次移动的距离较大,因而总的比较和移动次数较少。

private static void qSort(sqlist & L,int low, int high)
{
if (low<high) { //
int pivotloc=partition(L,low,high); //以a[pivotloc]为基准元素将a[low:high]划分成3段a[low: pivotloc -1],a[pivotloc]和a[pivotloc +1:high],使得a[low: pivotloc-1]中任何元素小于等于a[pivotloc],a[pivotloc +1:high]中任何元素大于等于a[pivotloc]。

下标pivotloc在划分过程中确定。

qSort (L,low, pivotloc-1); //对左半段排序
qSort(L, pivotloc+1,high); //对右半段排序 }
}
Int Partition(sqlist &L,int low,int high)
{
L.r[0]=L.r[low];//用子表第一个元素作为轴
Pivotkey = L.r[low].key;
While(low<high)
{
While(low<high&&L.r[high].key>=privotkey )
High--;
If(L.r[high].key<privotkey)
R[low]=r[high];
While(low<high&&L.r[low].key<=privotkey)
Low++;
If(L.r[low].key>privotkey)
R[high]=r[low];
}
L.r[low]=L.r[0];
Return low;
}
归并排序:
public static void mergeSort(Comparable a[], int left, int right)
{
int m = (left+right)/2; //取中点
if(left>=right)
return;
if(left+1==right)
{
if(a[left]>a[right])
std::swap(a[left], a[right]);
return;
}
mergeSort(a, left, m);
mergeSort(a, m+1, right);
merge(a, left,m, right); //合并到数组a
}
}
void Merge(A[], int l, int m, int h)
{
int i = l;
int j = m+1;
int k = 0; while(i<=m&&j<=h)
{
if(A[i]<A[j])
{
B[k++] = A[i];
i++;
}
else
{
B[k++] = A[j];
j++;
}
}
while(i<=m)
B[k++] = A[i++];
while(j<=h)
B[k++] = A[j++];
for(i=l; i<=h; i++)
A[i] = B[i-l];
}
二分法:
#include<iostream>
#define N 10
using namespace std;
int main()
{
int a[N],front,end,mid,x,i;
cout<<"请输入已排好序的a数组元素:"<<endl;
for(i=0;i<N;i++)
cin>>a[i];
cout<<"请输入待查找的数x:"<<endl;
cin>>x;
front=0;
end=N-1;
mid=(front+end)/2;
while(front<=end&&a[mid]!=x)
{
if(a[mid]<x)front=mid+1;
if(a[mid]>x)end=mid-1;
mid=(front+end)/2;
}
if(a[mid]!=x)
cout<<"没找到!"<<endl;
else
cout<<"找到了!在第"<<mid+1<<"项里。

"<<endl;
return 0;
}
二叉树递归、非递归遍历
package edu.cumt.jnotnull;
import java.util.Stack;
public class BinaryTree {
protected Node root;
public BinaryTree(Node root) {
this.root = root;
}
public Node getRoot() {
return root;
}
/** 构造树 */
p ublic static Node init() {
Node a = new Node('A');
Node b = new Node('B', null, a);
Node c = new Node('C');
Node d = new Node('D', b, c);
Node e = new Node('E');
Node f = new Node('F', e, null);
Node g = new Node('G', null, f);
Node h = new Node('H', d, g);
return h;// root
}
/** 访问节点 */
p ublic static void visit(Node p) {
System.out.print(p.getKey() + " ");
}
/** 递归实现前序遍历 */
p rotected static void preorder(Node p) {
if (p != null) {
visit(p);
preorder(p.getLeft());
preorder(p.getRight());
}
}
/** 递归实现中序遍历 */
p rotected static void inorder(Node p) {
if (p != null) {
inorder(p.getLeft());
visit(p);
inorder(p.getRight());
}
}
/** 递归实现后序遍历 */
p rotected static void postorder(Node p) {
if (p != null) {
postorder(p.getLeft());
postorder(p.getRight());
visit(p);
}
}
/** 非递归实现前序遍历 */
protected static void iterativePreorder2(Node p) {
Stack<Node> stack = new Stack<Node>();
Node node = p;
while (node != null || stack.size() > 0) {
while (node != null) {//压入所有的左节点,压入前访问它
visit(node);
stack.push(node);
node = node.getLeft();
}
if (stack.size() > 0) {//
node = stack.pop();
node = node.getRight();
}
}
}
/** 非递归实现后序遍历 */
protected static void iterativePostorder(Node p) {
Node q = p;
Stack<Node> stack = new Stack<Node>();
while (p != null) {
// 左子树入栈
for (; p.getLeft() != null; p = p.getLeft())
stack.push(p);
// 当前节点无右子或右子已经输出
while (p != null && (p.getRight() == null || p.getRight() == q)) {
visit(p);
q = p;// 记录上一个已输出节点
if (stack.empty())
return;
p = stack.pop();
}
// 处理右子
stack.push(p);
p = p.getRight();
}
}
/** 非递归实现后序遍历双栈法 */
p rotected static void iterativePostorder2(Node p) {
Stack<Node> lstack = new Stack<Node>();
Stack<Node> rstack = new Stack<Node>();
Node node = p, right;
do {
while (node != null) {
right = node.getRight();
lstack.push(node);
rstack.push(right);
node = node.getLeft();
}
node = lstack.pop();
right = rstack.pop();
if (right == null) {
visit(node);
} else {
lstack.push(node);
rstack.push(null);
}
node = right;
} while (lstack.size() > 0 ||
rstack.size() > 0);
}
/** 非递归实现后序遍历单栈法*/
p rotected static void iterativePostorder3(Node p) {
Stack<Node> stack = new Stack<Node>();
Node node = p, prev = p;
while (node != null || stack.size() > 0) { while (node != null) {
stack.push(node);
node = node.getLeft();
}
if (stack.size() > 0) {
Node temp = stack.peek().getRight();
if (temp == null || temp == prev) {
node = stack.pop();
visit(node);
prev = node;
node = null;
} else {
node = temp;
}
}
}
}
/** 非递归实现后序遍历4 双栈法*/
p rotected static void iterativePostorder4(Node p) {
Stack<Node> stack = new Stack<Node>();
Stack<Node> temp = new Stack<Node>();
Node node = p;
while (node != null || stack.size() > 0) { while (node != null) {
temp.push(node);
stack.push(node);
node = node.getRight();
}
if (stack.size() > 0) {
node = stack.pop();
node = node.getLeft();
}
}
while (temp.size() > 0) {
node = temp.pop();
visit(node);
}
}
/** 非递归实现中序遍历 */
p rotected static void iterativeInorder2(Node p) {
Stack<Node> stack = new Stack<Node>();
Node node = p;
while (node != null || stack.size() > 0) { while (node != null) {
stack.push(node);
node = node.getLeft();
}
if (stack.size() > 0) {
node = stack.pop();
visit(node);
node = node.getRight();
}
}
}
/**
* @param args
*/
p ublic static void main(String[] args) {
BinaryTree tree = new BinaryTree(init());
System.out.print(" Pre-Order:");
preorder(tree.getRoot());
System.out.println();
System.out.print(" In-Order:");
inorder(tree.getRoot());
System.out.println();
System.out.print("Post-Order:");
postorder(tree.getRoot());
System.out.println();
System.out.print(" Pre-Order:");
iterativePreorder(tree.getRoot());
System.out.println();
System.out.print("Pre-Order2:");
iterativePreorder2(tree.getRoot());
System.out.println();
System.out.print(" In-Order:");
iterativeInorder(tree.getRoot());
System.out.println();
System.out.print(" In-Order2:");
iterativeInorder2(tree.getRoot());
System.out.println();
System.out.print(" Post-Order:");
iterativePostorder(tree.getRoot());
System.out.println();
System.out.print("Post-Order2:");
iterativePostorder2(tree.getRoot());
System.out.println();
System.out.print("Post-Order3:");
iterativePostorder3(tree.getRoot());
System.out.println();
System.out.print("Post-Order4:");
iterativePostorder4(tree.getRoot());
System.out.println();
}
}
字符串反转
//字符串反转
char *reverse(char *str)
{
int len = strlen(str);
char temp ;
int i;
char *str1;
str1 = (char*)malloc(len);
memset(str1,0,len);
memcpy(str1,str,len);
for( i=0; i <len/2; i++)
{
temp = str1[i];
str1[i] = str1[len-1-i];//*(str+len-1-i); //执行到该行出现系统错误
str1[len-1-i]= temp;
}
return str1;
}
function reverse(arg) {
if(arg.length == 0) {
return arg;
}
else {
return reverse(arg.substr(1,arg.length)) + arg.substr(0,1);
}
}
alert(reverse("123456"));
2009-01-23 00:26
快速排序的原理倒是挺简单,选一个基准,将其余的元素与之对比分别放在左右两侧,左大右小,每次对比都是对其所有的元素,也就是说每一次都是n次对比。

他是一个递归的算法。

相信很多人不明白为什么他是n*log2n而不是
n*n,我当时也遇到了这样的问题,既然是对每一个元素都进行了对比,而每一次是n,为什么不是n*n呢?
那么可以这样看,假设对n个元素排序用时T(n) 我们可以根据原理得出T(n) = n + 2*T(n/2)
= 2n + 4*T(n/4)
= 3n + 8*T(n/8) ........................
= n*log2n
数学上,就是这样得到的。

相信有人就能反应上来了,如果还没明白,可以这样看。

每一次排序都比较了n次,这个是毋庸置疑的。

问题是进行了多少趟,这里的趟就是一次n次比较的过程。

一个n个元素的序列,当分枝长度为1的时候,就完成了,每次分枝都是比原先分支数多一倍。

可见,一个n序列,经过log2n就完成了到1的分枝。

每次分枝都是n次比较,所以总共n*long2n
至于最好情况和最坏情况,无非就是分支的次数所决定,上述的n*log2n是每次都将原序列分为等长的两部分,最坏的是,没法分,所以就是分了n 次
最坏的是n*n,而存储空间本来是log2n,即递归的次数,变为了n,n次递归。

相关文档
最新文档