12.3 重新编写12.7,使用头和尾指针分别以一个单独的指针传递给函数,而不是作为一个节点的一部分

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define TRUE 1
  4. #define FALSE 0
  5.  
  6. //指针fwd指向前一个节点,bwd指向后一个节点
  7. typedef struct NODE {
  8. struct NODE *fwd;
  9. struct NODE *bwd;
  10. int value;
  11. } Node;
  12.  
  13. /*传入指向 头部和尾部节点的指针 的指针,四种情况
  14. * 插入到表头,
  15. * 插入到表尾,
  16. * 插入到空表中,
  17. * 插入到表中,前三个都需要修改headPtr或tailPtr指针
  18. */
  19. int doubleLinklistInsert(Node **headPtr, Node **tailPtr, int value)
  20. {
  21. Node *this = *headPtr;
  22. Node *newNode;
  23.  
  24. while( this != NULL && this -> value < value){
  25. this = this -> fwd;
  26. }
  27.  
  28. newNode = (Node *)malloc(sizeof(Node));
  29. newNode -> value = value;
  30.  
  31. if(this == NULL){
  32. //插入到表尾,或者空表中
  33. if(this == *headPtr){
  34. //插入到空表
  35. *headPtr = newNode;
  36. *tailPtr = newNode;
  37. newNode -> fwd = NULL;
  38. newNode -> bwd = NULL;
  39. }else{
  40. //插入到表尾
  41. newNode -> fwd = NULL;
  42. //原来的表尾元素为当前节点的前节点
  43. newNode -> bwd = *tailPtr;
  44. (*tailPtr) -> fwd = newNode;
  45. //更新尾节点指针
  46. *tailPtr = newNode;
  47. }
  48. }else{
  49. //插入到表头,或者表中
  50. if(this == *headPtr){
  51. //插入到表头
  52. newNode -> bwd = NULL;
  53. //原来的表头变成第二个节点
  54. newNode -> fwd = *headPtr;
  55. (*headPtr) -> bwd = newNode;
  56. //更新表头
  57. *headPtr = newNode;
  58. }else{
  59. //插入到非空表中this位置的前面
  60. newNode -> fwd = this;
  61. newNode -> bwd = this -> bwd;
  62. this -> bwd -> fwd = newNode;
  63. this -> bwd = newNode;
  64. }
  65. }
  66.  
  67. return TRUE;
  68. }
  69.  
  70. int main()
  71. {
  72. Node third;
  73. Node second;
  74. Node first;
  75.  
  76. third = (Node){NULL, &second, 4};
  77. second = (Node){&third, &first, 2};
  78. first = (Node){&second, NULL, 1};
  79.  
  80. Node *head = &first;
  81. Node *tail = &third;
  82.  
  83. doubleLinklistInsert(&head, &tail, 35);
  84. doubleLinklistInsert(&head, &tail, 3);
  85. doubleLinklistInsert(&head, &tail, -10);
  86.  
  87. Node *rootPtr = head;
  88. while(rootPtr != NULL){
  89. printf("%d\t", rootPtr -> value);
  90. rootPtr = rootPtr -> fwd;
  91. }
  92. return 0;
  93. }

  运行:

12.4 编写函数反序排列单链表所有节点。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define TRUE 1
  4. #define FALSE 0
  5.  
  6. typedef struct Node {
  7. struct Node *next;
  8. int value;
  9. } Linklist;
  10.  
  11. Linklist *sll_reverse(Linklist *first)
  12. {
  13. if(first == NULL){
  14. return NULL;
  15. }
  16.  
  17. Linklist *current = first;
  18. Linklist *next;
  19. Linklist *pre;
  20. Linklist *morePre = NULL;
  21.  
  22. while((next = current -> next) != NULL){
  23. //循环移动当前指向的节点
  24. pre = current;
  25. current = next;
  26. //修改前一节点的next指针为前前节点
  27. pre -> next = morePre;
  28. //移动前前节点morePre的指针
  29. morePre = pre;
  30. }
  31.  
  32. //如果为单个节点之间返回
  33. if(current == first){
  34. return first;
  35. }else{
  36. //修改最后一个节点的指针,作为头指针返回原来的最后一个节点的位置
  37. current -> next = pre;
  38. return current;
  39. }
  40. }
  41.  
  42. int main()
  43. {
  44. Linklist third = {NULL, 4};
  45. Linklist second = {&third, 3};
  46. Linklist first = {&second, 2};
  47. Linklist *head = &first;
  48.  
  49. head = sll_reverse(head);
  50.  
  51. while (head != NULL){
  52. printf("%d\t", head -> value);
  53. head = head -> next;
  54. }
  55. return 0;
  56. }

  运行:

12.5 编写程序,从一个单链表中删除一个节点,第一个参数为指向链表头部的指针的指针

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define TRUE 1
  4. #define FALSE 0
  5.  
  6. typedef struct Node {
  7. struct Node *next;
  8. int value;
  9. } Linklist;
  10.  
  11. //从first指向的链表中删除节点node
  12. int sll_delete(Linklist **first, Linklist *node)
  13. {
  14. Linklist **ptr = first;
  15. //Ptr为指向 next字段的 指针
  16. while(*ptr != NULL && *ptr != node){
  17. ptr = &((*ptr) -> next);
  18. }
  19. //如果没有找到
  20. if(*ptr == NULL){
  21. return FALSE;
  22. }else{
  23. //如果找到了,变更前节点指向
  24. *ptr = (*ptr) -> next;
  25. //释放节点内存
  26. free(*ptr);
         return FALSE;
  27. }
  28. }
  29.  
  30. int main()
  31. {
  32. Linklist third = {NULL, 3};
  33. Linklist second = {&third, 2};
  34. Linklist first = {&second, 1};
  35. Linklist *headPtr = &first;
  36.  
  37. Linklist *head = headPtr;
  38. while (head != NULL){
  39. printf("%d\t", head -> value);
  40. head = head -> next;
  41. }
  42. printf("\n");
  43.  
  44. sll_delete(&headPtr, &second);
  45. head = headPtr;
  46. while (head != NULL){
  47. printf("%d\t", head -> value);
  48. head = head -> next;
  49. }
  50. printf("\n");
  51.  
  52. sll_delete(&headPtr, &first);
  53. head = headPtr;
  54. while (head != NULL){
  55. printf("%d\t", head -> value);
  56. head = head -> next;
  57. }
  58. printf("\n");
  59.  
  60. sll_delete(&headPtr, &third);
  61. head = headPtr;
  62. while (head != NULL){
  63. printf("%d\t", head -> value);
  64. head = head -> next;
  65. }
  66. return 0;
  67. }

  

运行:

12.6 双链表中移除节点,第一个参数为指向链表头部的指针,

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define TRUE 1
  4. #define FALSE 0
  5.  
  6. typedef struct Node {
  7. struct Node *next;
  8. int value;
  9. } Linklist;
  10.  
  11. //从first指向的链表中删除节点node
  12. int sll_delete(Linklist *first, Linklist *node)
  13. {
  14. Linklist *pre = NULL;
  15. Linklist *cur = first;
  16.  
  17. while(cur != NULL && cur != node){
  18. pre = cur;
  19. cur = cur -> next;
  20. }
  21.  
  22. //如果没有找到
  23. if(cur == NULL){
  24. return FALSE;
  25. }else if(cur == first){
  26. //此时first是传值传入,只可以修改头指针指向的值,修改为第二个节点
  27. *first = *(cur -> next);
  28. free(node);
  29. return TRUE;
  30. }else{
  31. pre -> next = cur -> next;
  32. free(node);
  33. return TRUE;
  34. }
  35. }
  36.  
  37. int main()
  38. {
  39. Linklist third = {NULL, 3};
  40. Linklist second = {&third, 2};
  41. Linklist first = {&second, 1};
  42. Linklist *headPtr = &first;
  43.  
  44. Linklist *head = headPtr;
  45. while (head != NULL){
  46. printf("%d\t", head -> value);
  47. head = head -> next;
  48. }
  49. printf("\n");
  50.  
  51. sll_delete(headPtr, &second);
  52. head = headPtr;
  53. while (head != NULL){
  54. printf("%d\t", head -> value);
  55. head = head -> next;
  56. }
  57. printf("\n");
  58.  
  59. sll_delete(headPtr, &first);
  60. while (headPtr != NULL){
  61. printf("%d\t", headPtr -> value);
  62. headPtr = headPtr -> next;
  63. }
  64. printf("\n");
  65.  
  66. sll_delete(headPtr, &third);
  67. head = headPtr;
  68. while (head != NULL){
  69. printf("%d\t", head -> value);
  70. head = head -> next;
  71. }
  72. printf("\n");
  73. return 0;
  74. }

运行:

12.7 建立单词索引表

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define TRUE 1
  5. #define FALSE 0
  6. #define EXIST 1
  7. #define NOEXIST 0
  8. typedef struct Wordlist {
  9. struct Wordlist *nextWord;
  10. char *word;
  11. } wordlist;
  12.  
  13. typedef struct Alphalist {
  14. struct Alphalist *nextAlpha;
  15. //单个单词链表的指针
  16. wordlist * wlPtr;
  17. char alpha;
  18. } alphalist;
  19.  
  20. int isExist(wordlist *listPtr, char *string)
  21. {
  22. wordlist *current = listPtr;
  23.  
  24. while(current != NULL){
  25. if(strcmp(string, current -> word) == 0){
  26. return EXIST;
  27. }
  28. current = current -> nextWord;
  29. }
  30.  
  31. return NOEXIST;
  32. }
  33.  
  34. int wordInsert(wordlist **listPtr, char *string)
  35. {
  36. wordlist **current = listPtr;
  37. wordlist *new;
  38. char *temp;
  39.  
  40. while(*current != NULL){
  41. //按字符排序进行插入
  42. if(strcmp(string, (*current) -> word) < 0){
  43. //生成new节点,插入到current之前,current为指向nextWord字段的指针
  44. new = (wordlist *)malloc(sizeof(wordlist));
  45. temp = (char *)malloc(strlen(string));
  46. if(temp == NULL){
  47. return FALSE;
  48. }
  49. strcpy(temp, string);
  50. new -> word = temp;
  51. //new指向 *current
  52. new -> nextWord = *current;
  53. //更新 *current为当前插入点
  54. *current = new;
  55. return TRUE;
  56. }
  57. //循环到下一点
  58. current = &(*current) -> nextWord;
  59. }
  60. //循环玩整个列表后,还未找到,则末尾追加上
  61. temp = (char *)malloc(strlen(string));
  62. if(temp == NULL){
  63. return FALSE;
  64. }
  65. strcpy(temp, string);
  66. new = (wordlist *)malloc(sizeof(wordlist));
  67. new -> word = temp;
  68. new -> nextWord = NULL;
  69. *current = new;
  70.  
  71. return TRUE;
  72. }
  73.  
  74. int WordAlphaListInsert(alphalist *ptr, char *string)
  75. {
  76. char headCh = string[0];
  77. alphalist *current = ptr;
  78. wordlist *wl;
  79. wordlist **rootPtr;
  80. char *temp;
  81.  
  82. //通过首字符查找wordlist
  83. while (current -> alpha != headCh){
  84. current = current -> nextAlpha;
  85. }
  86.  
  87. //已经存在
  88. if(isExist(current -> wlPtr, string) == EXIST){
  89. return FALSE;
  90. }else{
  91. //如果wordlist为NULL空,则创建初始单词链表
  92. if(current -> wlPtr == NULL){
  93. wl = (wordlist *)malloc(sizeof(wordlist));
  94. //第一个节点,nextword为NULL
  95. wl -> nextWord = NULL;
  96. //申请内存拷贝字符串
  97. temp = (char *)malloc(strlen(string));
  98. if(temp == NULL){
  99. return FALSE;
  100. }
  101. strcpy(temp, string);
  102. wl ->word = temp;
  103. current -> wlPtr = wl;
  104. }else{
  105. //如果有单词表,则插入单词
  106. rootPtr = &(current -> wlPtr);
  107. wordInsert(rootPtr, string);
  108. }
  109. return TRUE;
  110. }
  111. }
  112.  
  113. //打印链表内容
  114. void printList(alphalist *list)
  115. {
  116. alphalist *currentAl = list;
  117. wordlist *currentWl;
  118. while (currentAl != NULL){
  119. printf("%c:\n", currentAl -> alpha);
  120. currentWl = currentAl -> wlPtr;
  121. while (currentWl != NULL){
  122. printf("%s \t", currentWl -> word);
  123. currentWl = currentWl -> nextWord;
  124. }
  125. printf("\n-----------------------\n");
  126. currentAl = currentAl -> nextAlpha;
  127. }
  128. }
  129.  
  130. int main()
  131. {
  132. char z;
  133. alphalist *pre = NULL;
  134. alphalist *current;
  135.  
  136. //创建字母和单词列表
  137. for(z = 122; z > 96; z--){
  138. current = (alphalist *)malloc(sizeof(alphalist));
  139. current -> alpha = z;
  140. current -> wlPtr = NULL;
  141. current -> nextAlpha = pre;
  142. pre = current;
  143. }
  144. //插入单词
  145. WordAlphaListInsert(current, "yang");
  146. WordAlphaListInsert(current, "xun");
  147. WordAlphaListInsert(current, "xan");
  148. WordAlphaListInsert(current, "xzn");
  149. WordAlphaListInsert(current, "wu");
  150. WordAlphaListInsert(current, "ya");
  151. WordAlphaListInsert(current, "yz");
  152. printList(current);
  153.  
  154. return 0;
  155. }

运行:

C和指针 第十二章 结构体 习题的更多相关文章

  1. C和指针 第十二章 结构体 整体赋值 error: expected expression

    定义结构体后整体赋值时发生错误 typedef struct NODE { struct NODE *fwd; struct NODE *bwd; int value; } Node; //声明变量 ...

  2. C语言程序设计(十二) 结构体和共用体

    第十二章 结构体和共用体 当需要表示复杂对象时,仅使用几个基本数据类型显然是不够的 根本的解决方法是允许用户自定义数据类型 构造数据类型(复合数据类型)允许用户根据实际需要利用已有的基本数据类型来构造 ...

  3. C和指针 第十二章 使用结构和指针

    链表是一种常用的数据结构,每个节点通过链或者指针链接在一起,程序通过间接指针访问链表中的节点. typedef struct Node { //指向下一个节点的指针 struct Node *next ...

  4. C和指针 第十二章 使用结构和指针 双链表和语句提炼

    双链表中每个节点包含指向当前和之后节点的指针,插入节点到双链表中需要考虑四种情况: 1.插入到链表头部 2.插入到链表尾部 3.插入到空链表中 4.插入到链表内部 #include <stdio ...

  5. C和指针 (pointers on C)——第十二章:利用结构和指针

    第十二章 利用结构和指针 这章就是链表.先单链表,后双向链表. 总结: 单链表是一种使用指针来存储值的数据结构.链表中的每一个节点包括一个字段,用于指向链表的下一个节点. 有一个独立的根指针指向链表的 ...

  6. perl5 第十二章 Perl5中的引用/指针

    第十二章 Perl5中的引用/指针 by flamephoenix 一.引用简介二.使用引用三.使用反斜线(\)操作符四.引用和数组五.多维数组六.子程序的引用  子程序模板七.数组与子程序八.文件句 ...

  7. [CSAPP笔记][第十二章并发编程]

    第十二章 并发编程 如果逻辑控制流在时间上是重叠,那么它们就是并发的(concurrent).这种常见的现象称为并发(concurrency). 硬件异常处理程序,进程和Unix信号处理程序都是大家熟 ...

  8. 《OpenCL异构并行编程实战》补充笔记散点,第五至十二章

    ▶ 第五章,OpenCL 的并发与执行模型 ● 内存对象与上下文相关而不是与设备相关.设备在不同设备之间的移动如下,如果 kernel 在第二个设备上运行,那么在第一个设备上产生的任何数据结果在第二个 ...

  9. PRML读书会第十二章 Continuous Latent Variables(PCA,Principal Component Analysis,PPCA,核PCA,Autoencoder,非线性流形)

    主讲人 戴玮 (新浪微博: @戴玮_CASIA) Wilbur_中博(1954123) 20:00:49 我今天讲PRML的第十二章,连续隐变量.既然有连续隐变量,一定也有离散隐变量,那么离散隐变量是 ...

随机推荐

  1. HDU 1848 Fibonacci again and again【SG函数】

    对于Nim博弈,任何奇异局势(a,b,c)都有a^b^c=0. 延伸: 任何奇异局势(a1, a2,… an)都满足 a1^a2^…^an=0 首先定义mex(minimal excludant)运算 ...

  2. NOIP模拟赛20161007

    %hzwer http://hzwer.com/7602.html 题目名称 “与” 小象涂色 行动!行动! 输入文件 and.in elephant.in move.in 输出文件 and.out ...

  3. Oracle 增删改查

    Oracle入门案例: 1.创建实体类Student 并重写ToString方法 package cn.happy.entity; public class Student { public Inte ...

  4. Log4j

    [1]从零开始 a). 新建Java Project>>新建package>>新建java类: b). import jar包(一个就够),这里我用的是log4j-1.2.14 ...

  5. PHP开发工具+电子书+视频教程等资料下载汇总

    本汇总帖包括如下内容: PHP开发工具.PHP IDE PHP学习资源 基础.进阶类 PHP学习资源 高级及应用类 经典PHP视频教程系列 1. PHP开发工具.PHP IDE: PHP开发工具:Ze ...

  6. perl 调用shell脚本

    perl调用shell命令 perl调用shell shell调用perl Perl执行shell命令的几种方式及其区别

  7. LeetCode:Multiply Strings

    题目链接 Given two numbers represented as strings, return multiplication of the numbers as a string. Not ...

  8. PHP中使用CURL请求页面,使用fiddler进行抓包

    在PHP中使用CURL访问页面: <?php $ch = curl_init('http://www.baidu.com'); curl_setopt($ch, CURLOPT_RETURNTR ...

  9. WPF实现物理效果 拉一个小球

    一直以来都对物理效果有神秘感,完全不知道怎么实现的.直到看到了周银辉在老早前写的一篇博客:http://www.cnblogs.com/zhouyinhui/archive/2007/06/23/79 ...

  10. 关于jsp页面将表单填入数据库出现中文乱码绝对解决方案

    在所有jsp页面中添加两句话1.<%@ page language="java" contentType="text/html; charset=utf-8&quo ...