1 堆和栈的区别是什么,什么时候用堆什么时候用栈?
栈区:由编译器自动分配释放,存放函数参数,局部变量
堆区:由用户分配释放,若不释放,程序结束时可能有os收回
全局(静态)区:全局变量和静态(static)变量
文本常量区:常量字符串等放在此处,程序结束又系统释放
代码区:存放二进制代码
2:链表和数组的优缺点?
链表:链表是一块不连续的动态空间,长度可变;链表需要按顺序检索节点,效率低;
链表的优点是可以快速插入和删除节点,大小动态分配,长度不固定。
链表不存在越界问题。
数组:数组是一快连续的空间,声明时长度就需要固定。
数组的优点是速度快,数据操作直接使用偏移地址。
数组有越界问题.
3 树的深度优先遍历
递归
4 广度优先搜索算法
宽度优先搜索算法(又称广度优先搜索),是最简便的图的搜索算法之一,也是很多重要图的算法的原型.prim最小生成树算法采用类似的思想
5 树的非递归实现
class node
{
public:
int _data;
node *_l;
node *_r;
node *_p;
node( int val = 0 ) : _data(val), _l(NULL), _r(NULL), _p(NULL){}
};
class tree
{
public:
node *_root;
tree() : _root(NULL){}
void insert( node **h , node *n )
{
if ( n == NULL)
return;
if ( (*h) == NULL )
{
(*h) = n;
return;
}
else
{
if ( (*h)->_data >= n->_data )
{
insert( &(*h)->_l, n );
}
else
{
insert( &(*h)->_r, n );
}
}
}
void insert_non_recursion( node *n )
{
if ( n == NULL ) return;
node **tp = &_root;
while( (*tp) != NULL )
{
if ( (*tp)->_data >= n->_data )
{
tp = &(*tp)->_l;
}
else
{
tp = &(*tp)->_r;
}
}
(*tp) = n;
}
void traversal( node * n )
{
if ( n != NULL )
{
traversal( n->_l );
cout << n->_data <<" ";
traversal( n->_r );
}
else
{
return;
}
}
void traversal_non_recursion()
{
stack<node *> sn;
node *p = _root;
while( p !=NULL || sn.size() > 0 )
{
if ( p != NULL )
{
sn.push(p);
p = p->_l;
}
else
{
p = sn.top();
sn.pop();
cout << p->_data << " ";
p = p->_r;
}
}
}
void traversal_breadth()
{
queue<node *> qn;
node *p = _root;
if ( p != NULL )
qn.push(p);
while( qn.size() > 0 )
{
p = qn.front();
qn.pop();
cout << p->_data << " ";
if ( p->_l != NULL )
{
qn.push( p->_l );
}
if ( p->_r != NULL )
{
qn.push( p->_r );
}
}
}
};
6 请实现两棵树是否相等的比较,相等返回,否则返回其他值,并说明算法复杂度。
数据结构为:
typedef struct_TreeNode{
char c;
TreeNode *leftchild;
TreeNode *rightchild;
}TreeNode;
函数接口为:int CompTree(TreeNode* tree1,TreeNode* tree2);
注:A、B两棵树相等当且仅当Root->c==RootB-->c,而且A和B的左右子树相等或者左右互换相等。
int compTree(TreeNode *tree1, TreeNode *tree2)
{
if(!tree1 && !tree2) return 1;
if((tree1 && !tree2) ||(!tree1 && tree2)) return 0;
if(tree1 && tree2)
{
if(tree1->c==tree2->c)
{
if(compTree(tree1->leftChild, tree2->leftChild))
return compTree(tree1->rightChild, tree2->rightChild);
else if(compTree(tree1->rightChild, tree2->leftChild))
return compTree(tree1->leftChild, tree2->rightChild);
}
}
return 0;
}
7 编程实现
/*
该函数实现返回一个以“\0”结束的字符串中最长的数字串的长度,
并把该数字子串的首地址赋给outputstr
不能使用任何库函数或已经存在的函数,如strlen。
例如:在字符串“abc123abcdef12345abcdefgh123456789”中,
把该字符串的首地址赋给inputstr,函数返回,
outputstr指向字符串“”的首地址.
ASCII码--十进制(对应关系)
0--48 9--57 A--65 Z--90 a--97 z—122
*/
#define ISNUMCHAR(c) ( (c >= 48) && ( c <= 57 ) )
int maxContinueNum(const char *inputstr, const char **outputstr)
{
const char *p = inputstr;
int maxnum = 0;
int localnum = 0;
while( (*p++) != 0 )
{
if( ISNUMCHAR(*p) )
{
localnum ++;
if( localnum > maxnum )
{
maxnum = localnum;
(*outputstr) = p;
}
}
else
{
localnum = 0;
}
}
(*outputstr) -= (maxnum - 1);
return maxnum;
}
8 写一段程序,找出数组中第k大小的数,输出数所在的位置。例如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。
函数接口为:int find_orderk(const int* narry,const int n,const int k)
9 已知一个字串由GBK汉字和ansi编码的数字字母混合组成,编写c语言函数实现从中去掉所有ansi编码的字母和数字(包括大小写),要求在原字串上返回结果。
函数接口为:int filter_ansi(char* gbk_string)
注:汉字的GBK编码范围是0x8140-0xFEFE
10 对任意输入的正整数N,编写C程序求N!的尾部连续0的个数,并指出计算复杂度。如:18!=6402373705728000,尾部连续0的个数是3。
(不用考虑数值超出计算机整数界限的问题)