原文: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. js date 相关

  2. android handler messageQueue,looper

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 处理器获取 当前线程中的 循环器对象, 循环器 从 消息队列中 取出 消息, 给 处理器 ...

  3. 某gov的逻辑漏洞

    首先找一个号 在企业信息里面查看到大量的企业名称和组织机构代码 随后去找回密码那 可以看到是直接显示了用户名和密码 随后去登录 可以看到大量的工程信息个企业注册信息 ​

  4. bzoj 4034

    我写的是 DFS序+线段树 DFS序(出去的位置要单独建点)上,进入的位置是权值,出去的位置是权值的相反数,可以证明节点i到根节点的路径上的点的权值和是DFS序上1-in[i]的和. 只要搞出每个区间 ...

  5. Java中日期类型和mysql中日期类型进行整合

      1. java与mysql中日期.时间类型总结: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 mysql(版本:5.1.50)的时间日期类型如下:   da ...

  6. python mac环境搭建

    安装 virtualenv $ sudo pip install virtualenv 然后建立一个测试目录: $ mkdir testvirtual $ cd testvirtual 就可以成功创建 ...

  7. 简单的文件上传html+ashx

    前台页面:<form action="upload.ashx" method="post" enctype="multipart/form-da ...

  8. ng-show和ng-if的区别

    第一点区别是, ng-if 在后面表达式为 true 的时候才创建这个 dom 节点, ng-show 是初始时就创建了,用display:block 和 display:none 来控制显示和不显示 ...

  9. jquery.uploadify 使用过程

    HTML: <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"& ...

  10. LM358资料及引脚图

    LM358里面包括有两个高增益.独立的.内部频率补偿的双运放,适用于电压范围很宽的单电源,而且也适用于双电源工作方式,它的应用范围包括传感放大器.直流增益模块和其他所有可用单电源供电的使用运放的地方使 ...