数据结构 链表排序Word格式文档下载.docx
《数据结构 链表排序Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《数据结构 链表排序Word格式文档下载.docx(48页珍藏版)》请在冰豆网上搜索。
=n;
i++)//将R[d+1..n]分别插入各组当前的有序区
if(R[i].key<
R[i-d].key){
R[0]=R;
j=i-d;
//R[0]只是暂存单元,不是哨兵
do{//查找R的插入位置
R[j+d]=R[j];
//后移记录
j=j-d;
//查找前一记录 }
while(j>
0&
&
R[0].key<
R[j].key);
R[j+d]=R[0];
//插入R到正确的位置上
}//endif
}//ShellPass
2)选择排序
对待排序的记录序列进行n-1遍的处理,第1遍处理是将L[1..n]中最小者与L[1]交换位置,第2遍处理是将L[2..n]中最小者与L[2]交换位置,......,第i遍处理是将L中最小者与L交换位置。
这样,经过i遍处理之后,前i个记录的位置就已经按从小到大的顺序排列好了
voidSelectSort(RecordTyper[],intlength)
/*对记录数组r做简单选择排序,length为数组的长度*/
{ n=length;
for(i=1;
i<
=n-1;
++i)
{ k=i;
for(j=i+1;
j<
=n;
++j)
if(r[j].key<
r[k].key)k=j;
if(k!
=i)
{x=r[i];
r[i]=r[k];
r[k]=x;
}
}/*SelectSort*/
3)快速排序
#include<
iostream>
usingnamespacestd;
voidQuickSort(int*pData,intleft,intright)
inti(left),j(right),middle(0),iTemp(0);
middle=pData[(left+right)/2];
//求中间值
middle=pData[(rand()%(right-left+1))+left];
//生成大于等于left小于等于right的随机数
do{
while((pData[i]<
middle)&
(i<
right))//从左扫描大于中值的数
i++;
while((pData[j]>
middle)&
(j>
left))//从右扫描小于中值的数
j--;
//找到了一对值,交换
if(i<
=j)
{
iTemp=pData[j];
pData[j]=pData[i];
pData[i]=iTemp;
i++;
}
while(i<
=j);
//如果两边扫描的下标交错,就停止(完成一次)
//当左边部分有值(left<
j),递归左半边
if(left<
j)
{ QuickSort(pData,left,j);
//当右边部分有值(right>
i),递归右半边
if(right>
i){ QuickSort(pData,i,right);
} }
3.递归/非递归实现Fibonacci
//递归计算Fibonacci
typedefunsignedlongulong;
ulongFiblnacci(intn)
{
if(n<
=2)
{
return1;
}
returnFiblnacci(n-1)+Fiblnacci(n-2);
//非递归
ulongFibonacci(intn)
ulongresult;
ulongprev_result;
ulongnext_result;
result=prev_result=1;
while(n>
2)
n--;
next_result=prev_result;
prev_result=result;
result=prev_result+next_result;
returnresult;
本文来自CSDN博客,转载请标明出处:
3.1输入一个单链表,输出该单链表中倒数第k个节点
倒数第k个(对应节点数为n的链表)节点的编号为n+1-k,所以从第一个节点移动n-k次即可。
structnode*fun(structnode*head,intk)
intlen=0,i=0;
structnode*p=head;
while(p)
len++;
p=p->
next;
p=head;
for(i=1;
len+1-k;
i++)
returnp;
4.在链表里如何发现循环链接?
步长法。
1)初始化两个指针,p=head,q=head
2)循环遍历链表
next;
q=q->
next->
next
如果有p=q的时刻,则说明为循环链表
否则为非循环链表
这个算法的思想是:
可以看做两个在那里跑步,一个速度快,一个速度慢,当链表中有个环存在时,相当于这两个人在围绕一个圈跑步,那么跑得快的总会在某一时刻追上那个跑得慢的。
/判断是否为循环链表
boolLink:
:
isLoop()
Note*s,*f;
//快慢指针
s=head->
f=head->
while(s!
=NULL&
f!
f->
next!
=NULL)
if(s==f)
returntrue;
s=s->
f=f->
returnfalse;
}
5.给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里(代码?
)
假设数组Card[0-53]中的54个数对应54张牌,从第一张牌(i=0)开始直到倒数第二张牌(i=52),每次生成一个[i,53]之间的数r,将Card[i]和Card[r]中的数互换
生成指定范围内的随机数:
rand()%(n-m)+m
6.写一个函数,检查字符是否是整数,如果是,返回其整数值。
(或者:
怎样只用4行代码编写出一个从字符串到长整形的函数?
)
参考atoi函数
7.给出一个函数来输出一个字符串的所有排列
采用递归的思路,每一层递归的任务是输出当前string[begin,end]的每一个字母,在输出chara=string[begin]之后,对string[begin+1,end]进行递归调用。
递归调用结束之后再输出string[begin,end]的第二个字母。
然后对string[begin+2,end]进行递归调用。
例如"
1234"
第一层递归遍历"
,并且输出'
1'
,之后对"
234"
进行递归。
第二层递归遍历"
这时候用首字母'
2'
代替在第一层递归中'
后面的'
,然后在'
后面添加一个'
,于是输出"
12"
。
第三层递归输出"
123"
第四层递归输出"
然后退回到第三层递归。
在将'
4'
添加到"
后面被输出之后,本来依次输出'
之后的元素,但是'
已经是结尾,于是退回到第二层。
在第二层中,out之中已有"
,而且已经输出了"
后的第一个元素'
3'
,所以下一步是输出"
后的第二个元素'
,所以下一个输出"
124"
以此类推。
其中还需要防止输出完全相同的的子串。
如果是"
1224"
,不能输出两次"
(分别是第2个'
和第3个'
)。
所以在处理的时候需要判断之前是否已经出现过和当前元素一样的元素。
如果有则说明当前元素的工作已经被之前同样的元素做了,不需要再做。
这个判断的区间是[rec,i](i为当前元素下标,rec为本层递归需要被轮番代替的那个位置)。
voidCombine(charin[],charout[],intlength,intrec,intstart)
inti,j;
boolflag;
for(i=start;
i<
length;
i++)
flag=false;
if(i>
start)
for(j=i-1;
j>
=rec;
j--)
if(in[j]==in[i])
flag=true;
if(flag)
continue;
out[rec]=in[i];
out[rec+1]='
cout<
<
out<
endl;
if(i<
length-1)
Combine(in,out,length,rec+1,i+1);
8.请编写实现malloc()内存分配函数功能一样的代码(忽略)
9.给出一个函数来复制两个字符串A和B。
字符串A的后几个字节和字符串B的前几个字节重叠。
10.怎样编写一个程序,把一个有序整数数组放到二叉树中
structstudent{
intvalue;
structstudent*lchild;
structstudent*rchild;
};
voidarraytotree(int*a,intlen,structstudent**p){
if(len){
*p=(structstudent*)malloc(sizeof(structstudent));
(*p)->
value=a[len/2];
arraytotree(a,len/2,&
((*p)->
lchild));
arraytotree(a+len/2+1,len-len/2-1,&
rchild));
}else{
*p=NULL;
11.怎样从顶部开始逐层打印二叉树结点数据?
请编程
12.怎样把一个链表掉个顺序,单链表的反序(也就是反序,注意链表的边界条件并考虑空链表)?
voidreverselist(type&
phead1){
typephead2,pbuffer;
phead2=null;
pbuffer=phead1;
while(pbuffer!
=null){
phead1=phead1->
pbuffer->
next=phead2;
phead2=pbuffer;
phead1=phead2;
×
8
http:
//www.log4life.info/notebook/cc-os-data-structure-questions-related-to-surface-aggregate/
1.class和struct有啥区别?
struct和union有啥区别?
2.为什么析构函数经常是虚函数?
3.static这个关键字有哪些不同的用途?
4.构造函数可不可以是虚函数?
5.变量的定义与声明有什么区别?
变量定义放在头文件中会带来什么问题?
声明变量不分配空间,定义变量要分配空间。
多个文件include某个头文件,编译这些文件引起变量重复定义
6.实现函数atoi(或itoa,strcpy,strcmp,memcpy,strstr,strchr等等不一而足)
voiditoa(intn,chars[])
inti,sign;
if((sign=n)<
0)n=-n;
i=0;
do
s[i++]=n%10+'
0'
}while((n/=10)>
0);
if(sign<
0)s[i++]='
-'
s[i]='
\0'
reverse(s);
char*strcpy(char*dest,constchar*src)
char*szRet;
memset(szRet,0,sizeof(szRet));
if(NULL==dest&
NULL==src){
returnNULL;
*szRet=dest;
while((*dest++=*src++)!
);
returnszRet;
intstrcmp(constchar*src,constchar*dst)
intret=0;
while(!
(ret=*(unsignedchar*)src-*(unsignedchar*)dst)&
*dst)
++src,++dst;
if(ret<
0)
ret=-1;
elseif(ret>
ret=1;
return(ret);
void*memcpy(void*destaddr,voidconst*srcaddr,size_tlen)
char*dest=destaddr;
charconst*src=srcaddr;
while(len-->
0)
*dest++=*src++;
returndestaddr;
staticconstchar*_strstr(constchar*s1,constchar*s2)
assert(s2&
s1);
constchar*p=s1,*r=s2;
while(*p!
='
while(*p++==*r++);
if(*r=='
else
r=s2;
p=++s1;
char*strchr(char*s,charc)
char*p=s;
while(*s&
*s!
=c)
s++;
if(*s==c)
printf("
所需要匹配的位置为:
%d\n"
s-p);
没有找到匹配的!
"
returns;
char*strcpy(char*strdest,constchar*strsrc)
assert((strdest!
=Null)&
(strsrc!
=NULl));
char*address=strdest;
while((*strdest++=*strsrc++)!
returnaddress;
intstrlen(constchar*str)
assert(str!
=NULL);
intlen;
while((*str++)!
returnlen;
7.解释宏和函数的优缺点
答:
内联函数和宏一样快,没有函数调用的额外开销,但是提供正常函数的类型检测
8.C++里面是不是所有的动作都是main()引起的?
如果不是,请举例
比如全局对象将在程序的main()函数被调用之前创建
9.什么是内链函数?
内联函数在编译时是否做参数类型检查?
内联函数要做参数类型检查,这是内联函数跟宏相比的优势
操作系统相关
堆和栈有什么区别?
什么时候分配内存用的是堆?
什么时候用的是栈?
10.什么是缓冲区溢出?
有什么危害?
为什么会造成缓冲区溢出?
11.什么是回调函数?
如何定义和实现一个类的成员函数为回调函数?
12.什么是临界区?
如何解决冲突?
13.Linux下进程之间通信有哪几种方式?
线程呢?
14.如何在一个文件中删除一个字符?
15.什么是Unicode?
在做Unicode相关处理的时候要注意什么?
数据结构相关
二叉树:
16.二叉树的广/深度优先遍历算法,递归/非递归怎么写?
1)广度遍历(即层次遍历)算法
typedefNODEDataType;
/////////队列定义
typedefstruct
DataTypedata[MAX+1];
intfront,rear;
}Queue;
///1)队列初始化
voidInitQueue(Queue&
q)
q.front=0;
q.rear=0;
//2)判断队列是不是为空
intEmptyQueue(Queue&
if(q.rear==q.front)
return1;
else
return0;
//3)依次进队列元素
voidInsertQueue(Queue&
q,DataTypex)
if(q.rear==MAX)
cout<
<
"
满了\n"
q.rear++;
q.data[q.rear]=x;
//4)出队列地一个元素,输出这个元素
voidDeleteQueue(Queue&
q,NODE&
p)
if(EmptyQueue(q))
队列已经为空\n"
p=q.data[q.front+1];
q.front++;
//5)输出队列的元素个数
intNumberQueue(Queue&
return(q.rear-q.front);
voidTravelTree(NODEtree)//层次遍历用队列来实现
Queueq;
InitQueue(q);
NODEp,p1,p2;
p=tree;
if(p)
InsertQueue(q,p);
while(!
EmptyQueue(q))
DeleteQueue(q,p);
p->
data<
****"
endl;
p1=p->
Lsubtree;
p2=p->
Rsubtree;
if(p1)
InsertQueue(q,p1);
if(p2)
InsertQueue(q,p2);
2)深度遍历(即先序遍历)
17.写程序计算二叉树的高度
template<
typenameT>
staticintDepth(BSTreeNode<
T>
*pbs)
if(pbs==NULL)
return0;
intld=Depth(pbs->
left);
intrd=Depth(pbs->
right);
return1+(ld>
rd?
ld:
rd);
18.如何判断一个二叉树是否是平衡二叉树?
根据平衡