原文: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. 顺序线性表之大整数求和C++实现

    顺序线性表之大整数求和 大整数求和伪代码 1.初始化进位标志 flag=0: 2.求大整数 A 和 B 的长度: int aLength = a.GetLength(); int bLength = ...

  2. Java-----jar反编译修改重新打包

    http://blog.csdn.net/hekewangzi/article/details/44676797 一.使用反编译工具JD-GUI(JD-GUI相关操作见Java-----反编译clas ...

  3. 【对比分析二】Web Storage和cookie的区别

    1)  存储空间不同. a)  Web Storage能提供5MB的存储空间(不同浏览器的提供的空间不同).Cookie仅4KB. b)  Web Storage每个域(包括子域)有独立的存储空间,各 ...

  4. BZOJ 1022 [SHOI2008]小约翰的游戏John AntiNim游戏

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1475  Solved: 932[Submit][ ...

  5. (转,学习记录)MD5加密算法中的加盐值(SALT)

    我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码. 加Salt可以一定程度上解决这一问题.所谓加Salt方法,就 ...

  6. react父子组件数据传递

    子传父 1.首先父组件设定一个自定义函数 getChildDatas = (values) => { //...业务代码 } 2.将该函数暴露在子组件的引用上 <Child getChil ...

  7. [置顶] 解决EXTJS文本框长度验证在ORACLE数据库下不正确的问题

    由于ORACLE数据库里面一个汉字和符号占2 个字节,数字和英文占1个字节,所以用EXTJS的文本框MaxLenght去限制输入的长度是不正确的,因为EXTJS只限制了输入的字数量,而不是字节数量. ...

  8. springMVC 前台向后台传数组

    前台: $(function() {//点击播放按钮执行的事件 $("#button").click(function(e) { alert("kaishi chuanz ...

  9. transform,transition,animation 的混合使用——进阶

    今天我们来讲述css3能够做成动画的最小独立单元,并且讲述如何使用这些独立的单元来构成一个‘高大尚’的组合动画. 这是我在网上找的一个案例,修改后的效果图,虽说不是特别的‘高大尚’,但我认为这也跟高大 ...

  10. 使用jquery加载部分视图01-使用$.get()

    使用Html.RenderParital或Html.RenderAction可以在主视图中加载部分视图. 两种方法是有区别的,在"RenderPartial和RenderAction区别&q ...