原文: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 Function Arguments

    Function arguments在ECMAScript中的行为并不像其他大多数语言中的函数参数. 在ECMAScript中,function 并不关心有多少个参数传入函数中,也不关心传入参数的数据 ...

  2. [BZOJ4881][Lydsy1705月赛]线段游戏

    首先冷静一下看清问题的本质,是将整个数列分成两个递增子序列. 那么由Dilworth定理得,无解当且仅当数列的最长下降子序列的长度>2,先特判掉. 然后就有一些比较厉害的做法:http://ww ...

  3. 洛谷 P4884 多少个1?

    题面在这里 好久没做题了2333,竟然还一次A了,神奇 大概就是等比数列然后把分母乘过去,然后直接BSGS就行了,就是要写快速乘恩... #include<bits/stdc++.h> # ...

  4. .net mvc控制器传递方法到视图

    很多人都是在视图里面定义方法,然后再使用.我个人也是这么干的.但是为了验证是否可以将方法从控制器传递到视图,所以做了个测试.结果真的可以.原理是利用了委托(delegate),因为委托本身就是一种类型 ...

  5. 详解Object.constructor

    对象的constructor属性引用了该对象的构造函数.对于 Object 对象,该指针指向原始的 Object() 函数.如下: var obj = {}; obj.constructor //ƒ ...

  6. HK设备安全补丁升级方案

    1.背景:          当前很多HK行业设备的端口映射到公网上,其中一部分老版本设备是存在安全漏洞的,由于传统行业没有设备平台的概念,无法通过设备提示用户进行升级,导致这些存在漏洞的设备在互联网 ...

  7. Setup Factory打包winform程序

    摘要 Setup Factory是一款软件安装工具.Setup Factory支持创建一个安装文件或一个单间的setup.exe文件,生成文件可以运行于任意版本的windows中. 步骤 1.安装Se ...

  8. Android 手电筒源代码

    近期因为公司须要,做了一个手电筒,事实上手电筒原理非常easy,就是调用照相机的闪光灯,控制闪光灯的开关,就能够实现手电筒的效果, 强调一下,代码中一定要注意在结束的时候对闪光灯进行释放,否则就会导致 ...

  9. 29防止程序集被篡改仿冒,全局程序集缓存GAC

      为什么需要强名称程序集和数字签名 有一个类库项目ClassLib,对应的程序集是ClassLib.dll.当前控制台项目引用ClassLib.dll程序集的方式有2种: 1.通过添加现有项目 文件 ...

  10. Android之应用内部实现国际化

    这篇文章也提供了应用内部转换语言的方法: http://blog.csdn.net/sodino/article/details/6596709 .1和2的方法是一样的,然而还是会调整了手机的语言设置 ...