原文:http://1527zhaobin.iteye.com/blog/1537110
一.判断链表是否存在环型链表问题:
说明:判断一个链表是否存在环,例如下面这个链表就存在环,n1-->n2-->n3-->n4-->n5-->n2,环的开始结点是n5
解法:这里有个比较简单的解法:设两个指针p1,p2,每次循环p1向前走一步,之向前走两步,直到p2碰到NULL指针(无环)或两个指针相等结束循环算法(有环),即如果两个指针相等则说明存在环。
代码如下:
- struct link{
- int data;
- link * next;
- };
-
- bool isLoop(link * head){
-
- link* p1 = head,*p2 = head;
-
-
- if(head == NULL || head->next == NULL){
- return false;
- }
-
-
- do{
- p1 = p1->next;
- p2 = p2->next->next;
- }while(p2 && p2->next && p1!=p2);
-
-
- if(p1 == p2){
- return true;
- else
- return false;
- }
- struct link{
- int data;
- link * next;
- };
-
- bool isLoop(link * head){
-
- link* p1 = head,*p2 = head;
-
-
- if(head == NULL || head->next == NULL){
- return false;
- }
-
-
- do{
- p1 = p1->next;
- p2 = p2->next->next;
- }while(p2 && p2->next && p1!=p2);
-
-
- if(p1 == p2){
- return true;
- else
- return false;
- }
二.链表反转:
说明:链表反转,比如原链表是1-->2-->3-->4-->5 通过反转后成为5-->4-->3-->2-->1
解法一:利用三个指针,指向当前要反转的节点的指针,这个当前节点之前的节点指针,这个当前节点之后的节点指针;反转后再向后继续遍历
代码如下:
- struct linka{
- int data;
- link * next;
- };
-
- bool reverse(link * &head){
-
- if(head == NULL)
- return;
-
-
- linka * pre,*cur,*ne;
-
- pre = head;
- cur = head->next;
-
- while(cur){
- ne = cur->next;
- cur->next = pre;
- pre = cur;
- cur = ne;
- }
-
-
- head->next = NULL;
- head = pre;
- }
- struct linka{
- int data;
- link * next;
- };
-
- bool reverse(link * &head){
-
- if(head == NULL)
- return;
-
-
- linka * pre,*cur,*ne;
-
- pre = head;
- cur = head->next;
-
- while(cur){
- ne = cur->next;
- cur->next = pre;
- pre = cur;
- cur = ne;
- }
-
-
- head->next = NULL;
- head = pre;
- }
解法二:利用递归。这种方法的基本思想是在反转当前节点之前先调用递归函数反转后续节点。不过,这个方法有个缺点:在反转后的最后一个节点会形成一个环,所以必须将函数的返回节点的next设为NULL.因为要改变head指针,所以我用了引用
代码如下:
- struct linka{
- int data;
- link * next;
- };
-
- linka * reverse(linka * p,link * &head){
- if(p == NULL || p->next == NULL){
- head = p;
- return p;
- }else {
- linka* tmp = reverse(p->next,head);
- tmp->next = p;
- return p;
- }
- }
- struct linka{
- int data;
- link * next;
- };
-
- linka * reverse(linka * p,link * &head){
- if(p == NULL || p->next == NULL){
- head = p;
- return p;
- }else {
- linka* tmp = reverse(p->next,head);
- tmp->next = p;
- return p;
- }
- }
三.链表的合并:
说明:递增有序的2个单链表合并成一个递增有序的单链表,不用任何库函数调用
代码如下:
- <pre name="code" class="cpp">#include <iostream>
-
using namespace std;
-
-
-
struct node{
-
int value;
- node* next;
- };
-
-
-
void insertNode(node* head, int value){
- node* p = head->next;
-
if ( p == NULL ){
-
p = new node;
- p->value = value;
- p->next = NULL;
- head->next = p;
-
return;
- }
-
-
while ( p->next != NULL ){
- p = p->next;
- }
-
node* tmp = new node;
- tmp->value = value;
- tmp->next = NULL;
- p->next = tmp;
- }
-
-
-
void print(node* head){
- node* p = head->next;
-
while ( p != NULL ){
-
cout << p->value << " ";
- p = p->next;
- }
- cout << endl;
- }
-
-
-
-
-
-
void chg2sort(node* head, node* &p){
-
-
if (head->next == NULL ){
-
return;
- }
-
- node* s = head;
-
while ( s->next != p ){
- s = s->next;
- }
-
-
- node* q = p;
- node* r = q;
-
-
while ( q != NULL ){
-
-
if ( q->value <= p->value ){
-
r = q;
- q = q->next;
-
}else {
-
break;
- }
- }
-
-
-
-
if ( q == NULL ){
- r->next = p;
- s->next = p->next;
- p->next = NULL;
-
}else if ( q != NULL ){
- s->next = p->next;
- r->next = p;
- p->next = q;
- }
-
-
- p = s->next;
- }
-
-
-
- node* merge(node* head1, node* head2){
-
node* head;
- node* p = head1->next;
- node* q = head2->next;
-
-
-
if ( p == NULL ){
- head = head2;
-
return head;
-
}else if ( q == NULL ){
- head = head1;
-
return head;
- }
-
-
-
if ( (p != NULL) && (q != NULL) ){
-
if ( p->value < q->value ){
- head = head1;
-
}else{
- head = head2;
- }
- }
-
-
node* p_prior;
- node* q_prior;
-
-
while ( (p != NULL) && (q != NULL) ){
-
if ( p ->value < q->value ){
-
if ( head == head1 ){
- p_prior = p;
- p = p->next;
-
}else if ( head == head2 ){
-
-
int tmp = p->value;
- p->value = q->value;
- q->value = tmp;
-
chg2sort(head1, p);
- q_prior = q;
- q = q->next;
- }
-
}else if ( p->value == q->value ){
- p_prior = p;
- p = p->next;
- q_prior = q;
- q = q->next;
-
}else if ( p->value > q->value ){
-
if ( head == head1 ){
-
int tmp = p->value;
- p->value = q->value;
- q->value = tmp;
- chg2sort(head2, q);
- p_prior = p;
- p = p->next;
-
}else if ( head == head2 ){
- q_prior = q;
- q = q->next;
- }
- }
- }
-
-
if ( p != NULL ){
- q_prior->next = p;
- }
-
-
if ( q != NULL ){
- p_prior->next = q;
- }
-
-
return head;
- }
-
-
int main(){
-
-
int a[5] = {1, 5, 8, 10, 20};
-
node* headA = new node;
- headA->next = NULL;
-
-
for (int i = 0; i < 5; ++i){
- insertNode(headA, a[i]);
- }
-
- print(headA);
-
-
-
int b[3] = {3, 4, 9};
-
node* headB = new node;
- headB->next = NULL;
-
-
for (int i = 0; i < 3; ++i){
- insertNode(headB, b[i]);
- }
-
- print(headB);
-
- head = merge(headA, headB);
- print(head);
-
-
return 0;
- }
- <pre name="code" class="cpp">#include <iostream>
- using namespace std;
-
- struct node{
- int value;
- node* next;
- };
-
- void insertNode(node* head, int value){
- node* p = head->next;
- if ( p == NULL ){
- p = new node;
- p->value = value;
- p->next = NULL;
- head->next = p;
- return;
- }
-
- while ( p->next != NULL ){
- p = p->next;
- }
- node* tmp = new node;
- tmp->value = value;
- tmp->next = NULL;
- p->next = tmp;
- }
-
- void print(node* head){
- node* p = head->next;
- while ( p != NULL ){
- cout << p->value << " ";
- p = p->next;
- }
- cout << endl;
- }
-
-
-
- void chg2sort(node* head, node* &p){
-
- if (head->next == NULL ){
- return;
- }
-
- node* s = head;
- while ( s->next != p ){
- s = s->next;
- }
-
-
- node* q = p;
- node* r = q;
-
- while ( q != NULL ){
-
- if ( q->value <= p->value ){
- r = q;
- q = q->next;
- }else {
- break;
- }
- }
-
-
-
- if ( q == NULL ){
- r->next = p;
- s->next = p->next;
- p->next = NULL;
- }else if ( q != NULL ){
- s->next = p->next;
- r->next = p;
- p->next = q;
- }
-
-
- p = s->next;
- }
-
-
- node* merge(node* head1, node* head2){
- node* head;
- node* p = head1->next;
- node* q = head2->next;
-
-
- if ( p == NULL ){
- head = head2;
- return head;
- }else if ( q == NULL ){
- head = head1;
- return head;
- }
-
-
- if ( (p != NULL) && (q != NULL) ){
- if ( p->value < q->value ){
- head = head1;
- }else{
- head = head2;
- }
- }
-
- node* p_prior;
- node* q_prior;
-
- while ( (p != NULL) && (q != NULL) ){
- if ( p ->value < q->value ){
- if ( head == head1 ){
- p_prior = p;
- p = p->next;
- }else if ( head == head2 ){
-
- int tmp = p->value;
- p->value = q->value;
- q->value = tmp;
- chg2sort(head1, p);
- q_prior = q;
- q = q->next;
- }
- }else if ( p->value == q->value ){
- p_prior = p;
- p = p->next;
- q_prior = q;
- q = q->next;
- }else if ( p->value > q->value ){
- if ( head == head1 ){
- int tmp = p->value;
- p->value = q->value;
- q->value = tmp;
- chg2sort(head2, q);
- p_prior = p;
- p = p->next;
- }else if ( head == head2 ){
- q_prior = q;
- q = q->next;
- }
- }
- }
-
- if ( p != NULL ){
- q_prior->next = p;
- }
-
- if ( q != NULL ){
- p_prior->next = q;
- }
-
- return head;
- }
-
- int main(){
-
- int a[5] = {1, 5, 8, 10, 20};
- node* headA = new node;
- headA->next = NULL;
-
- for (int i = 0; i < 5; ++i){
- insertNode(headA, a[i]);
- }
-
- print(headA);
-
-
- int b[3] = {3, 4, 9};
- node* headB = new node;
- headB->next = NULL;
-
- for (int i = 0; i < 3; ++i){
- insertNode(headB, b[i]);
- }
-
- print(headB);
-
- head = merge(headA, headB);
- print(head);
-
- return 0;
- }
如果可以用库函数合并的话:代码如下:
- Node* mergeAction(Node* head1, Node* head2){
-
-
Node* head=(Node*)malloc(sizeof(Node));
-
Node* q=head;
-
while(head1 && head2){
-
if(head1->data<=head2->data){
-
Node* p=(Node*)malloc(sizeof(Node));
- p->data=head1->data;
- p->next=NULL;
- q->next=p;
- q=q->next;
- head1=head1->next;
- }
-
else if(head1->data > head2->data){
-
Node* p=(Node*)malloc(sizeof(Node));
- p->data=head2->data;
- p->next=NULL;
- q->next=p;
- q=q->next;
- head2=head2->next;
- }
- }
-
return head->next;
- }
- Node* mergeAction(Node* head1, Node* head2){
- Node* head=(Node*)malloc(sizeof(Node));
- Node* q=head;
- while(head1 && head2){
- if(head1->data<=head2->data){
- Node* p=(Node*)malloc(sizeof(Node));
- p->data=head1->data;
- p->next=NULL;
- q->next=p;
- q=q->next;
- head1=head1->next;
- }
- else if(head1->data > head2->data){
- Node* p=(Node*)malloc(sizeof(Node));
- p->data=head2->data;
- p->next=NULL;
- q->next=p;
- q=q->next;
- head2=head2->next;
- }
- }
- return head->next;
- }
四.判断两个数组中是否存在相同的数字,给定两个排好序的数据,怎么高效得判断这两个数组中存在相同的数字:
说明:O(n)算法,因为两个数组都是排序好的,所以只要一次遍历就行了,首先设两个下标,分别初始化为两个数
组的起始地址,依次向前推进,推进的规则是比较两个数组中的数字,小的那个数组的下标各前推进一步,直到任何一个数组的下标到达数组末尾时,如果这时还没
碰到相同的数字,说明数组中没有相同的数字。
代码如下:
- bool findcommon2(int a[], int size1,int b[],int size2){
-
int i = 0, j = 0;
-
-
while(i<size1 && j<size2){
-
if(a[i]==b[j])
-
return true;
-
-
if(a[i]>b[j])
-
j++;
-
-
if(a[i]<b[j])
-
i++;
- }
-
-
return false;
- }
- bool findcommon2(int a[], int size1,int b[],int size2){
- int i = 0, j = 0;
-
- while(i<size1 && j<size2){
- if(a[i]==b[j])
- return true;
-
- if(a[i]>b[j])
- j++;
-
- if(a[i]<b[j])
- i++;
- }
-
- return false;
- }
五.按单词反转字符串:
说明:单词用空格分开,如,Here is blog.csdn.net/wufenglong
经过反转后变为:blog.csdn.net/wufenglong is
Here如果只是简单的将所有字符串翻转的话,可以遍历字符串,将第一个字符和最后一个交换,第二个和倒数第二个交换,依次循环。其实按照单词反转的话可
以在第一遍遍历的基础上,再遍历一遍字符串,对每一个单词再反转一次,这样每个单词又恢复了原来的顺序
代码如下:
- char * reverse_word(const char *str){
-
int len = strlen(str);
-
char * restr = new char[len+1];
-
- strcpy(restr,str);
-
-
-
for(int i=0,j=len-1;i<j;i++,j--){
-
char tmp = restr[i];
- restr[i] = restr[j];
- restr[j] = tmp;
- }
-
-
-
int i,j,k = 0;
-
while(k<len){
- i=j=k;
-
while(restr[j]!=‘ ‘ && restr[j]!=‘\0‘)
-
j++;
-
-
k = j+1;
- j--;
-
-
-
for(;i<j;i++,j--){
-
char tmp = restr[i];
- restr[i] = restr[j];
- restr[j] = tmp;
- }
- }
-
-
return restr;
- }
- char * reverse_word(const char *str){
- int len = strlen(str);
- char * restr = new char[len+1];
-
- strcpy(restr,str);
-
-
- for(int i=0,j=len-1;i<j;i++,j--){
- char tmp = restr[i];
- restr[i] = restr[j];
- restr[j] = tmp;
- }
-
-
- int i,j,k = 0;
- while(k<len){
- i=j=k;
- while(restr[j]!=‘ ‘ && restr[j]!=‘\0‘)
- j++;
-
- k = j+1;
- j--;
-
-
- for(;i<j;i++,j--){
- char tmp = restr[i];
- restr[i] = restr[j];
- restr[j] = tmp;
- }
- }
-
- return restr;
- }
六.字符串反转:
题意:给定一个字符串,一个这个字符串的子串,将第一个字符串反转,但保留子串的顺序不变。
例如:输入 每一个串 “this is wufl‘s Chinese site: http://blog.csdn.net/wufenglong”
子串:“wufl”
输出: gnolgnefuw/tne.ndsc/golb//:ptth:eits esenihC s‘wufl si siht
说明:一般的方法是先扫描一边第一个字符串,然后用stack把它反转,同时记录下子串出现的位置。然后再扫描一遍把记录下来的子串再用stack反转,我用的方法是用一遍扫描数组的方法,扫描中如果发现子串,就将子串倒过来压入堆栈。
代码如下:
- #include <stack>
-
using namespace std;
-
-
-
const char * reverse(const char * s1, const char * token){
- assert(s1 && token);
-
-
stack<char> stack1;
-
-
const char * ptoken = token, *head = s1, *rear =s1;
-
-
while(*head !=‘‘){
-
while(*head !=‘‘ && *ptoken == *head){
- ptoken++;
- head++;
- }
-
-
if(*ptoken==‘‘){
-
const char *p;
-
-
for(p=head-1;p>=rear;p--){
- stark1.push(*p);
- }
-
- ptoken = token;
- rear = head;
-
}else{
- stack1.push(*rear);
- head = ++rear;
- ptoken = token;
- }
- }
-
-
char * returnV = new char[strlen(s1)+1];
-
int i=0;
-
-
while(!stack1.empty()){
- returnV[i++] = stack1.top();
- stack1.top();
- }
-
-
returnV[i]="";
-
return returnV;
- }
- #include <stack>
- using namespace std;
-
- const char * reverse(const char * s1, const char * token){
- assert(s1 && token);
-
- stack<char> stack1;
-
- const char * ptoken = token, *head = s1, *rear =s1;
-
- while(*head !=‘‘){
- while(*head !=‘‘ && *ptoken == *head){
- ptoken++;
- head++;
- }
-
- if(*ptoken==‘‘){
- const char *p;
-
- for(p=head-1;p>=rear;p--){
- stark1.push(*p);
- }
-
- ptoken = token;
- rear = head;
- }else{
- stack1.push(*rear);
- head = ++rear;
- ptoken = token;
- }
- }
-
- char * returnV = new char[strlen(s1)+1];
- int i=0;
-
- while(!stack1.empty()){
- returnV[i++] = stack1.top();
- stack1.top();
- }
-
- returnV[i]="";
- return returnV;
- }
1. 在一个单链表中p所指结点之前插入一个s (值为e)所指结点时,可执行如下操作:
q=head;
while (q->next!=p) q=q->next;
s= new Node; s->data=e;
q->next= ; //填空
s->next= ; //填空
2. 线性表的顺序存储结构是一种 的存储结构,而链式存储结构是一种___的存储结构。
A.随机存取 B.索引存取 C.顺序存取 D.散列存取
3. 线性表若采用链式存储结构时,要求内存中可用存储单元的地址___。
A. 必须是连续的 B. 部分地址必须是连续的
C. 一定是不连续的 D. 连续或不连续都可以
4. 在一个单链表中,已知q所指结点是p所指结点的前驱结点,若在q和p之间插入s结点,则执行____。
A. s->next=p->next; p->next=s; B. p->next=s->next; s->next=p;
C. q->next=s; s->next=p; D. p->next=s; s->next=q;
5. 在一个单链表中,若p所指结点不是最后结点,在p之后插入s所指结点,则执行____。
A. s->next=p; p->next=s; B. s->next=p->next; p->next=s;
C. s->next=p->next; p=s; C. p->next=s; s->next=p;
6. 在一个单链表中,若删除p所指结点的后续结点,则执行____。
A. p->next= p->next->next; B. p= p->next; p->next= p->next->next;
C. p->next= p->next; D. p= p->next->next;
7. 链表不具备的特点是 ____ 。
A 可随机访问任何一个元素 B 插入、删除操作不需要移动元素
C 无需事先估计存储空间大小 D 所需存储空间与线性表长度成正比
8. 以下关于线性表的说法不正确的是 。
A 线性表中的数据元素可以是数字、字符、记录等不同类型。
B 线性表中包含的数据元素个数不是任意的。
C 线性表中的每个结点都有且只有一个直接前趋和直接后继。
D 存在这样的线性表:表中各结点都没有直接前趋和直接后继。
9. 在一个长度为n的顺序表中删除第i个元素,要移动 个元素。如果要在第i个元素前插入一个元素,要后移( )个元素。 N-I N-I+1
--------------------------------------------------------------------------------------------------
1. 栈操作数据的原则是( ),队列操作数据的原则是 ( ) 。
2. 在栈中,可进行插入和删除操作的一端称 。
3. 栈和队列都是____结构;对于栈只能在____插入和删除元素;对于队列只能在____插入元素和____删除元素。
4. 栈结构通常采用的两种存储结构是 和 。
5. 计算机在运行递归程序时,要用到 提供的栈。
6. 一个栈的入栈序列a,b,c,d,e,则栈的不可能的输出序列是____。
A. edcba B. decba C. dceab D. abcde
7. 一个队列的数据入列序列是1,2,3,4,则队列的出队时输出序列是____ 。
A. 4,3,2,1 B. 1,2,3,4 C. 1,4,3,2 D. 3,2,4,1
8. 判断一个表达式中左右括号是否匹配,采用 ____ 实现较为方便。
A 线性表的顺序存储 B 队列 C 线性表的链式存储 D 栈
9. 栈与一般线性表区别主要在方面 。
A 元素个数 B 元素类型 C 逻辑结构 D 插入、删除元素的位置
10. “假上溢”现象会出现在 中。
A 循环队列 B 队列 C 链队列 D 顺序队列
11. 在一个链队中,假设F和R分别是队首和队尾指针,则删除一个结点的运算是 。
A R=F->next; B R=R->next; C F=F->next; D F=R->next;
12. 表达式a*(b+c)-d的后缀表达式是 。
A.abcd*+- B. abc+*d- C. abc*+d- D. -+*abcd
C++数据结构面试题,布布扣,bubuko.com
C++数据结构面试题
原文:http://www.cnblogs.com/zhizhan/p/3821121.html