原文:http://1527zhaobin.iteye.com/blog/1537110

一.判断链表是否存在环型链表问题:

  说明:判断一个链表是否存在环,例如下面这个链表就存在环,n1-->n2-->n3-->n4-->n5-->n2,环的开始结点是n5

解法:这里有个比较简单的解法:设两个指针p1,p2,每次循环p1向前走一步,之向前走两步,直到p2碰到NULL指针(无环)或两个指针相等结束循环算法(有环),即如果两个指针相等则说明存在环。

代码如下:

  1. /*节点数据结构*/
  2. struct link{
  3. int data;
  4. link * next;
  5. };
  6. /*
  7. *判断是否有环的方法
  8. *
  9. *参数来头节点的指针
  10. */
  11. bool isLoop(link * head){
  12. //p1步长为1;p2步长为2
  13. link* p1 = head,*p2 = head;
  14. //如果只有一个节点或两个节点,直接return false
  15. if(head == NULL || head->next == NULL){
  16. return false;
  17. }
  18. //循环前进,直到p2走到NULL或p2追上p1
  19. do{
  20. p1 = p1->next;
  21. p2 = p2->next->next;
  22. }while(p2 && p2->next && p1!=p2);
  23. //如果有环
  24. if(p1 == p2){
  25. return true;
  26. else
  27. return false;
  28. }
  1. /*节点数据结构*/
  2. struct link{
  3. int data;
  4. link * next;
  5. };
  6. /*
  7. *判断是否有环的方法
  8. *
  9. *参数来头节点的指针
  10. */
  11. bool isLoop(link * head){
  12. //p1步长为1;p2步长为2
  13. link* p1 = head,*p2 = head;
  14. //如果只有一个节点或两个节点,直接return false
  15. if(head == NULL || head->next == NULL){
  16. return false;
  17. }
  18. //循环前进,直到p2走到NULL或p2追上p1
  19. do{
  20. p1 = p1->next;
  21. p2 = p2->next->next;
  22. }while(p2 && p2->next && p1!=p2);
  23. //如果有环
  24. if(p1 == p2){
  25. return true;
  26. else
  27. return false;
  28. }

二.链表反转:

说明:链表反转,比如原链表是1-->2-->3-->4-->5 通过反转后成为5-->4-->3-->2-->1

解法一:利用三个指针,指向当前要反转的节点的指针,这个当前节点之前的节点指针,这个当前节点之后的节点指针;反转后再向后继续遍历

代码如下:

  1. /*节点数据结构*/
  2. struct linka{
  3. int data;
  4. link * next;
  5. };
  6. /*
  7. *反转
  8. *
  9. *参数:头节点的指针的引用
  10. */
  11. bool reverse(link * &head){
  12. //只有一个节点,即不用反转,直接返回
  13. if(head == NULL)
  14. return;
  15. //定义3个辅助指针,pre指向当前要反转的节点的前一个节点;cur为当前要反转的节点;ne指向当前反转的节点的下一个节点
  16. linka * pre,*cur,*ne;
  17. //初始化指针
  18. pre = head;
  19. cur = head->next;
  20. //循环,直到cur为NULL
  21. while(cur){
  22. ne = cur->next;
  23. cur->next = pre;
  24. pre = cur;
  25. cur = ne;
  26. }
  27. //反转到最后,设置头节点指针
  28. head->next = NULL;
  29. head = pre;
  30. }
  1. /*节点数据结构*/
  2. struct linka{
  3. int data;
  4. link * next;
  5. };
  6. /*
  7. *反转
  8. *
  9. *参数:头节点的指针的引用
  10. */
  11. bool reverse(link * &head){
  12. //只有一个节点,即不用反转,直接返回
  13. if(head == NULL)
  14. return;
  15. //定义3个辅助指针,pre指向当前要反转的节点的前一个节点;cur为当前要反转的节点;ne指向当前反转的节点的下一个节点
  16. linka * pre,*cur,*ne;
  17. //初始化指针
  18. pre = head;
  19. cur = head->next;
  20. //循环,直到cur为NULL
  21. while(cur){
  22. ne = cur->next;
  23. cur->next = pre;
  24. pre = cur;
  25. cur = ne;
  26. }
  27. //反转到最后,设置头节点指针
  28. head->next = NULL;
  29. head = pre;
  30. }

解法二:利用递归。这种方法的基本思想是在反转当前节点之前先调用递归函数反转后续节点。不过,这个方法有个缺点:在反转后的最后一个节点会形成一个环,所以必须将函数的返回节点的next设为NULL.因为要改变head指针,所以我用了引用

代码如下:

  1. /*节点数据结构*/
  2. struct linka{
  3. int data;
  4. link * next;
  5. };
  6. /*
  7. *反转
  8. *
  9. *参数:头节点的指针的引用
  10. */
  11. linka * reverse(linka * p,link * &head){
  12. if(p == NULL || p->next == NULL){
  13. head = p;
  14. return p;
  15. }else {
  16. linka* tmp = reverse(p->next,head);
  17. tmp->next = p;
  18. return p;
  19. }
  20. }
  1. /*节点数据结构*/
  2. struct linka{
  3. int data;
  4. link * next;
  5. };
  6. /*
  7. *反转
  8. *
  9. *参数:头节点的指针的引用
  10. */
  11. linka * reverse(linka * p,link * &head){
  12. if(p == NULL || p->next == NULL){
  13. head = p;
  14. return p;
  15. }else {
  16. linka* tmp = reverse(p->next,head);
  17. tmp->next = p;
  18. return p;
  19. }
  20. }

三.链表的合并:

说明:递增有序的2个单链表合并成一个递增有序的单链表,不用任何库函数调用

代码如下:

  1. <pre name="code" class="cpp">#include <iostream>
  2. using namespace std;
  3. /* 单链表节点 */
  4. struct node{
  5. int value;
  6. node* next;
  7. };
  8. /* 给单链表添加节点 */
  9. void insertNode(node* head, int value){
  10. node* p = head->next;
  11. if ( p == NULL ){
  12. p = new node;
  13. p->value = value;
  14. p->next = NULL;
  15. head->next = p;
  16. return;
  17. }
  18. while ( p->next != NULL ){
  19. p = p->next;
  20. }
  21. node* tmp = new node;
  22. tmp->value = value;
  23. tmp->next = NULL;
  24. p->next = tmp;
  25. }
  26. /* 遍历输出链表节点 */
  27. void print(node* head){
  28. node* p = head->next;
  29. while ( p != NULL ){
  30. cout << p->value << " ";
  31. p = p->next;
  32. }
  33. cout << endl;
  34. }
  35. /* 下面实现不使用任何库函数, 利用交换的方法在原空间实现整体有序。 方法是先确定哪一个链表
  36. 的第一个节点的值小,把这个链表的头结点作为合并后链表的头结点,然后比较2个有序链表的当前节点
  37. 的值,如果代表最后合并链表的值小,则不用交换,否则把两个值交换,最后合并链表始终保持两个值中
  38. 的小值。另一个链表由于交换了一个元素,当前元素可能影响该链表的有序递增,对其进行调整使其保持
  39. 递增有序,然后重复上述动作,直到一个链表遍历结束,然后把剩余的链表连接起来就行。*/
  40. /* 调整链表的第一个节点,使其变成递增有序 */
  41. void chg2sort(node* head, node* &p){
  42. if (head->next == NULL ){ //没有节点,直接返回
  43. return;
  44. }
  45. node* s = head;
  46. while ( s->next != p ){ //s指向p的前一个节点
  47. s = s->next;
  48. }
  49. //下面的一段找到第一个大于p节点值的节点
  50. node* q = p;
  51. node* r = q;
  52. while ( q != NULL ){
  53. if ( q->value <= p->value ){
  54. r = q; //r始终指向q的前一个节点
  55. q = q->next;
  56. }else {
  57. break;
  58. }
  59. }
  60. //下面调整指针,其实可以统一写出来,为了阅读清晰把q为NULL和非NULL分开写出来
  61. if ( q == NULL ){
  62. r->next = p;
  63. s->next = p->next;
  64. p->next = NULL;
  65. }else if ( q != NULL ){
  66. s->next = p->next;
  67. r->next = p;
  68. p->next = q;
  69. }
  70. //由于链表进行了调换,当前链表指针也需要改变
  71. p = s->next;
  72. }
  73. /* 两个有序链表进行合并 */
  74. node* merge(node* head1, node* head2){
  75. node* head; //合并后的头指针
  76. node* p = head1->next;
  77. node* q = head2->next;
  78. //有一个链表为空的情况,直接返回另一个链表
  79. if ( p == NULL ){
  80. head = head2;
  81. return head;
  82. }else if ( q == NULL ){
  83. head = head1;
  84. return head;
  85. }
  86. //两个都不为空,先确定哪个链表作为合并后的链表
  87. if ( (p != NULL) && (q != NULL) ){
  88. if ( p->value < q->value ){
  89. head = head1;
  90. }else{
  91. head = head2;
  92. }
  93. }
  94. node* p_prior; //始终指向p节点的前一个节点
  95. node* q_prior;
  96. while ( (p != NULL) && (q != NULL) ){
  97. if ( p ->value < q->value ){
  98. if ( head == head1 ){//如果链表1的值小于链表2的值,链表1的指针向下指
  99. p_prior = p;
  100. p = p->next;
  101. }else if ( head == head2 ){
  102. //进行当前节点值的交换
  103. int tmp = p->value;
  104. p->value = q->value;
  105. q->value = tmp;
  106. chg2sort(head1, p); //交换元素后的调整
  107. q_prior = q;
  108. q = q->next;
  109. }
  110. }else if ( p->value == q->value ){//链表1的值等于链表2时,两链表指针都向下指
  111. p_prior = p;
  112. p = p->next;
  113. q_prior = q;
  114. q = q->next;
  115. }else if ( p->value > q->value ){
  116. if ( head == head1 ){//如果链表1的值大于链表2的值,交接两节点的值后,排序链表2后,再下指
  117. int tmp = p->value;
  118. p->value = q->value;
  119. q->value = tmp;
  120. chg2sort(head2, q);
  121. p_prior = p;
  122. p = p->next;
  123. }else if ( head == head2 ){
  124. q_prior = q;
  125. q = q->next;
  126. }
  127. }
  128. }
  129. if ( p != NULL ){
  130. q_prior->next = p;
  131. }
  132. if ( q != NULL ){
  133. p_prior->next = q;
  134. }
  135. return head;
  136. }
  137. int main(){
  138. /* 建立有序链表A */
  139. int a[5] = {1, 5, 8, 10, 20};
  140. node* headA = new node;
  141. headA->next = NULL;
  142. for (int i = 0; i < 5; ++i){
  143. insertNode(headA, a[i]);
  144. }
  145. print(headA);
  146. /* 建立有序链表B */
  147. int b[3] = {3, 4, 9};
  148. node* headB = new node;
  149. headB->next = NULL;
  150. for (int i = 0; i < 3; ++i){
  151. insertNode(headB, b[i]);
  152. }
  153. print(headB);
  154. head = merge(headA, headB);
  155. print(head);
  156. return 0;
  157. }
  1. <pre name="code" class="cpp">#include <iostream>
  2. using namespace std;
  3. /* 单链表节点 */
  4. struct node{
  5. int value;
  6. node* next;
  7. };
  8. /* 给单链表添加节点 */
  9. void insertNode(node* head, int value){
  10. node* p = head->next;
  11. if ( p == NULL ){
  12. p = new node;
  13. p->value = value;
  14. p->next = NULL;
  15. head->next = p;
  16. return;
  17. }
  18. while ( p->next != NULL ){
  19. p = p->next;
  20. }
  21. node* tmp = new node;
  22. tmp->value = value;
  23. tmp->next = NULL;
  24. p->next = tmp;
  25. }
  26. /* 遍历输出链表节点 */
  27. void print(node* head){
  28. node* p = head->next;
  29. while ( p != NULL ){
  30. cout << p->value << " ";
  31. p = p->next;
  32. }
  33. cout << endl;
  34. }
  35. /* 下面实现不使用任何库函数, 利用交换的方法在原空间实现整体有序。 方法是先确定哪一个链表
  36. 的第一个节点的值小,把这个链表的头结点作为合并后链表的头结点,然后比较2个有序链表的当前节点
  37. 的值,如果代表最后合并链表的值小,则不用交换,否则把两个值交换,最后合并链表始终保持两个值中
  38. 的小值。另一个链表由于交换了一个元素,当前元素可能影响该链表的有序递增,对其进行调整使其保持
  39. 递增有序,然后重复上述动作,直到一个链表遍历结束,然后把剩余的链表连接起来就行。*/
  40. /* 调整链表的第一个节点,使其变成递增有序 */
  41. void chg2sort(node* head, node* &p){
  42. if (head->next == NULL ){ //没有节点,直接返回
  43. return;
  44. }
  45. node* s = head;
  46. while ( s->next != p ){ //s指向p的前一个节点
  47. s = s->next;
  48. }
  49. //下面的一段找到第一个大于p节点值的节点
  50. node* q = p;
  51. node* r = q;
  52. while ( q != NULL ){
  53. if ( q->value <= p->value ){
  54. r = q; //r始终指向q的前一个节点
  55. q = q->next;
  56. }else {
  57. break;
  58. }
  59. }
  60. //下面调整指针,其实可以统一写出来,为了阅读清晰把q为NULL和非NULL分开写出来
  61. if ( q == NULL ){
  62. r->next = p;
  63. s->next = p->next;
  64. p->next = NULL;
  65. }else if ( q != NULL ){
  66. s->next = p->next;
  67. r->next = p;
  68. p->next = q;
  69. }
  70. //由于链表进行了调换,当前链表指针也需要改变
  71. p = s->next;
  72. }
  73. /* 两个有序链表进行合并 */
  74. node* merge(node* head1, node* head2){
  75. node* head; //合并后的头指针
  76. node* p = head1->next;
  77. node* q = head2->next;
  78. //有一个链表为空的情况,直接返回另一个链表
  79. if ( p == NULL ){
  80. head = head2;
  81. return head;
  82. }else if ( q == NULL ){
  83. head = head1;
  84. return head;
  85. }
  86. //两个都不为空,先确定哪个链表作为合并后的链表
  87. if ( (p != NULL) && (q != NULL) ){
  88. if ( p->value < q->value ){
  89. head = head1;
  90. }else{
  91. head = head2;
  92. }
  93. }
  94. node* p_prior; //始终指向p节点的前一个节点
  95. node* q_prior;
  96. while ( (p != NULL) && (q != NULL) ){
  97. if ( p ->value < q->value ){
  98. if ( head == head1 ){//如果链表1的值小于链表2的值,链表1的指针向下指
  99. p_prior = p;
  100. p = p->next;
  101. }else if ( head == head2 ){
  102. //进行当前节点值的交换
  103. int tmp = p->value;
  104. p->value = q->value;
  105. q->value = tmp;
  106. chg2sort(head1, p); //交换元素后的调整
  107. q_prior = q;
  108. q = q->next;
  109. }
  110. }else if ( p->value == q->value ){//链表1的值等于链表2时,两链表指针都向下指
  111. p_prior = p;
  112. p = p->next;
  113. q_prior = q;
  114. q = q->next;
  115. }else if ( p->value > q->value ){
  116. if ( head == head1 ){//如果链表1的值大于链表2的值,交接两节点的值后,排序链表2后,再下指
  117. int tmp = p->value;
  118. p->value = q->value;
  119. q->value = tmp;
  120. chg2sort(head2, q);
  121. p_prior = p;
  122. p = p->next;
  123. }else if ( head == head2 ){
  124. q_prior = q;
  125. q = q->next;
  126. }
  127. }
  128. }
  129. if ( p != NULL ){
  130. q_prior->next = p;
  131. }
  132. if ( q != NULL ){
  133. p_prior->next = q;
  134. }
  135. return head;
  136. }
  137. int main(){
  138. /* 建立有序链表A */
  139. int a[5] = {1, 5, 8, 10, 20};
  140. node* headA = new node;
  141. headA->next = NULL;
  142. for (int i = 0; i < 5; ++i){
  143. insertNode(headA, a[i]);
  144. }
  145. print(headA);
  146. /* 建立有序链表B */
  147. int b[3] = {3, 4, 9};
  148. node* headB = new node;
  149. headB->next = NULL;
  150. for (int i = 0; i < 3; ++i){
  151. insertNode(headB, b[i]);
  152. }
  153. print(headB);
  154. head = merge(headA, headB);
  155. print(head);
  156. return 0;
  157. }

如果可以用库函数合并的话:代码如下:

  1. Node* mergeAction(Node* head1, Node* head2){
  2. //两个链表的合并操作
  3. Node* head=(Node*)malloc(sizeof(Node));
  4. Node* q=head; //q指向合并后的链表的最后一个
  5. while(head1 && head2){ //
  6. if(head1->data<=head2->data){
  7. Node* p=(Node*)malloc(sizeof(Node)); //p是新生节点的指针
  8. p->data=head1->data;
  9. p->next=NULL;
  10. q->next=p;
  11. q=q->next;
  12. head1=head1->next;
  13. }
  14. else if(head1->data > head2->data){
  15. Node* p=(Node*)malloc(sizeof(Node));
  16. p->data=head2->data;
  17. p->next=NULL;
  18. q->next=p;
  19. q=q->next;
  20. head2=head2->next;
  21. }
  22. }
  23. return head->next;
  24. }
  1. Node* mergeAction(Node* head1, Node* head2){
  2. //两个链表的合并操作
  3. Node* head=(Node*)malloc(sizeof(Node));
  4. Node* q=head; //q指向合并后的链表的最后一个
  5. while(head1 && head2){ //
  6. if(head1->data<=head2->data){
  7. Node* p=(Node*)malloc(sizeof(Node)); //p是新生节点的指针
  8. p->data=head1->data;
  9. p->next=NULL;
  10. q->next=p;
  11. q=q->next;
  12. head1=head1->next;
  13. }
  14. else if(head1->data > head2->data){
  15. Node* p=(Node*)malloc(sizeof(Node));
  16. p->data=head2->data;
  17. p->next=NULL;
  18. q->next=p;
  19. q=q->next;
  20. head2=head2->next;
  21. }
  22. }
  23. return head->next;
  24. }

四.判断两个数组中是否存在相同的数字,给定两个排好序的数据,怎么高效得判断这两个数组中存在相同的数字:

说明:O(n)算法,因为两个数组都是排序好的,所以只要一次遍历就行了,首先设两个下标,分别初始化为两个数
组的起始地址,依次向前推进,推进的规则是比较两个数组中的数字,小的那个数组的下标各前推进一步,直到任何一个数组的下标到达数组末尾时,如果这时还没
碰到相同的数字,说明数组中没有相同的数字。

代码如下:

  1. bool findcommon2(int a[], int size1,int b[],int size2){
  2. int i = 0, j = 0;
  3. while(i<size1 && j<size2){
  4. if(a[i]==b[j])
  5. return true;
  6. if(a[i]>b[j])
  7. j++;//j标记b数组
  8. if(a[i]<b[j])
  9. i++;//i标记a数组
  10. }
  11. return false;
  12. }
  1. bool findcommon2(int a[], int size1,int b[],int size2){
  2. int i = 0, j = 0;
  3. while(i<size1 && j<size2){
  4. if(a[i]==b[j])
  5. return true;
  6. if(a[i]>b[j])
  7. j++;//j标记b数组
  8. if(a[i]<b[j])
  9. i++;//i标记a数组
  10. }
  11. return false;
  12. }

五.按单词反转字符串:

说明:单词用空格分开,如,Here is blog.csdn.net/wufenglong
经过反转后变为:blog.csdn.net/wufenglong is
Here如果只是简单的将所有字符串翻转的话,可以遍历字符串,将第一个字符和最后一个交换,第二个和倒数第二个交换,依次循环。其实按照单词反转的话可
以在第一遍遍历的基础上,再遍历一遍字符串,对每一个单词再反转一次,这样每个单词又恢复了原来的顺序

代码如下:

  1. char * reverse_word(const char *str){
  2. int len = strlen(str);
  3. char * restr = new char[len+1];
  4. strcpy(restr,str);
  5. //首尾交换,i是首的索引 j是尾的索引
  6. for(int i=0,j=len-1;i<j;i++,j--){
  7. char tmp = restr[i];
  8. restr[i] = restr[j];
  9. restr[j] = tmp;
  10. }
  11. //再把每个单词反转
  12. int i,j,k = 0;
  13. while(k<len){
  14. i=j=k;
  15. while(restr[j]!=' ' && restr[j]!='\0')
  16. j++;//j为空格的索引
  17. k = j+1;//k为
  18. j--;
  19. //反转单词
  20. for(;i<j;i++,j--){
  21. char tmp = restr[i];
  22. restr[i] = restr[j];
  23. restr[j] = tmp;
  24. }
  25. }
  26. return restr;
  27. }
  1. char * reverse_word(const char *str){
  2. int len = strlen(str);
  3. char * restr = new char[len+1];
  4. strcpy(restr,str);
  5. //首尾交换,i是首的索引 j是尾的索引
  6. for(int i=0,j=len-1;i<j;i++,j--){
  7. char tmp = restr[i];
  8. restr[i] = restr[j];
  9. restr[j] = tmp;
  10. }
  11. //再把每个单词反转
  12. int i,j,k = 0;
  13. while(k<len){
  14. i=j=k;
  15. while(restr[j]!=' ' && restr[j]!='\0')
  16. j++;//j为空格的索引
  17. k = j+1;//k为
  18. j--;
  19. //反转单词
  20. for(;i<j;i++,j--){
  21. char tmp = restr[i];
  22. restr[i] = restr[j];
  23. restr[j] = tmp;
  24. }
  25. }
  26. return restr;
  27. }

六.字符串反转:

题意:给定一个字符串,一个这个字符串的子串,将第一个字符串反转,但保留子串的顺序不变。

例如:输入 每一个串 “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反转,我用的方法是用一遍扫描数组的方法,扫描中如果发现子串,就将子串倒过来压入堆栈。

代码如下:

  1. #include <stack>
  2. using namespace std;
  3. //reverse the string 's1' ,the substring 'token'
  4. const char * reverse(const char * s1, const char * token){
  5. assert(s1 && token);
  6. stack<char> stack1;
  7. const char * ptoken = token, *head = s1, *rear =s1;
  8. while(*head !=''){
  9. while(*head !='' && *ptoken == *head){
  10. ptoken++;
  11. head++;
  12. }
  13. if(*ptoken==''){
  14. const char *p;
  15. for(p=head-1;p>=rear;p--){
  16. stark1.push(*p);
  17. }
  18. ptoken = token;
  19. rear = head;
  20. }else{
  21. stack1.push(*rear);
  22. head = ++rear;
  23. ptoken = token;
  24. }
  25. }
  26. char * returnV = new char[strlen(s1)+1];
  27. int i=0;
  28. while(!stack1.empty()){
  29. returnV[i++] = stack1.top();
  30. stack1.top();
  31. }
  32. returnV[i]="";
  33. return returnV;
  34. }
    1. #include <stack>
    2. using namespace std;
    3. //reverse the string 's1' ,the substring 'token'
    4. const char * reverse(const char * s1, const char * token){
    5. assert(s1 && token);
    6. stack<char> stack1;
    7. const char * ptoken = token, *head = s1, *rear =s1;
    8. while(*head !=''){
    9. while(*head !='' && *ptoken == *head){
    10. ptoken++;
    11. head++;
    12. }
    13. if(*ptoken==''){
    14. const char *p;
    15. for(p=head-1;p>=rear;p--){
    16. stark1.push(*p);
    17. }
    18. ptoken = token;
    19. rear = head;
    20. }else{
    21. stack1.push(*rear);
    22. head = ++rear;
    23. ptoken = token;
    24. }
    25. }
    26. char * returnV = new char[strlen(s1)+1];
    27. int i=0;
    28. while(!stack1.empty()){
    29. returnV[i++] = stack1.top();
    30. stack1.top();
    31. }
    32. returnV[i]="";
    33. return returnV;
    34. }

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++数据结构面试题的更多相关文章

  1. Java数据结构面试题

    1.栈和队列的共同特点是(只允许在端点处插入和删除元素) 4.栈通常采用的两种存储结构是(线性存储结构和链表存储结构) 5.下列关于栈的叙述正确的是(D)      A.栈是非线性结构B.栈是一种树状 ...

  2. 从一道索引数据结构面试题看B树、B+树

    题目1: Mysql数据库用过吧?l里面的索引是基于什么数据结构. 答:主要是基于Hash表和B+树 题目2: 很好请你说一下B+树的实现细节是什么样的?B-树和B+树有什么区别?联合索引在B+树中如 ...

  3. Java数据结构面试题,输出 最后一个 出现次数为1的字符

    今天去面试,遇到一个数据结构题,给定一个字符串,输出 最后一个 出现次数为1的字符 回来研究了下,代码如下: package com.pine.interview.test; import java. ...

  4. SQL数据库面试题

    SQL数据库面试题 1.SQL SREVER中,向一个表中插入了新数据,如何快捷的得到自增量字段的当前值 这种情况其实我们经常用到,比如我们新建了一个用户,建立完用户后我们希望马上得到这个新用户的ID ...

  5. Shell在大数据的魅力时代:从一点点思路百度大数据面试题

    供Linux开发中的同学们,Shell这可以说是一个基本功. 对于同学们的操作和维护.Shell也可以说是一种必要的技能,Shell.对于Release Team,软件配置管理的同学来说.Shell也 ...

  6. Shell在大数据时代的魅力:从一道百度大数据面试题想到的点滴

    对于在Linux下开发的同学来说,Shell可以说是一种基本功. 对于运维的同学来说,Shell可以说是一种必备的技能,而且应该要非常熟练的书写Shell.对于Release Team,软件配置管理的 ...

  7. [大数据面试题]hadoop核心知识点

    * 面试答案为LZ所写,如需转载请注明出处,谢谢. * 这里不涉及HiveSQL和HBase操作的笔试题,这些东西另有总结. 1.MR意义. MR是一个用于处理大数据的分布式离线计算框架,它采用”分而 ...

  8. SQL SERVER 数据库面试题

    1.用一条SQL语句 查询出每门课都大于80分的学生姓名 name   kecheng   fenshu 张三     语文       81张三     数学       75李四     语文   ...

  9. BAT大数据面试题

    1.kafka的message包括哪些信息 一个Kafka的Message由一个固定长度的header和一个变长的消息体body组成 header部分由一个字节的magic(文件格式)和四个字节的CR ...

随机推荐

  1. python opencv3 cornerHarris 角点检测

    git:https://github.com/linyi0604/Computer-Vision 角点也是处在一个无论框框往哪边移动 框框内像素值都会变化很大的情况而定下来的点 如果框框水平方向上移动 ...

  2. 在Windows上安装FFmpeg程序

    原文地址:http://helloway.blog.51cto.com/7666282/1642247 FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它提供了录 ...

  3. 【平面图最小割】BZOJ2007-[NOI2010]海拔

    [题目大意] 城市被东西向和南北向的主干道划分为n×n个区域,包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路.现得到了每天每条道路两个方向的人流量.每一个交叉路口都有海拔,每向上爬h ...

  4. Codeforces Round #288 (Div. 2) C. Anya and Ghosts 模拟 贪心

    C. Anya and Ghosts time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  5. Linux下nmon工具安装及nmon analyser的使用

    步骤一:下载nmon及nmon analyser工具 nmon:http://nmon.sourceforge.net/pmwiki.php 根据自己系统的版本下载相应的版本即可 nmon analy ...

  6. Linux性能监控分析命令(四)—top命令介绍

    性能监控分析的命令包括如下: 1.vmstat 2.sar 3.iostat 4.top 5.free 6.uptime 7.netstat 8.ps 9.strace 10.lsof ======= ...

  7. Mysql show indexes 查看索引状态

     查看表中有哪些已建立的索引 SHOW INDEX FROM tbl_name [FROM db_name] SHOW INDEX会返回以下字段: | Table | Non_unique | Key ...

  8. 我们为什么需要Map-Reduce?

    在讨论我们是否真的需要Map-Reduce这一分布式计算技术之前,我们先面对一个问题,这可以为我们讨论这个问题提供一个直观的背景. 问题 我们先从最直接和直观的方式出发,来尝试解决这个问题: 先伪一下 ...

  9. Tasker to detect application running in background

    We used to be told that tasker is only capable of detecting foreground application, if the app gets ...

  10. Assembly类

    System.Reflection.Assembly类是一个比较常用到的类,在反射中就经常用到. 由于这个类实在有太多的字段.属性与方法.实在不想将一个个属性方法从MSDN复制出来然后逐个属性.方法敲 ...