fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. //第5回:線形リスト(Linked List)
  5. //配列と違って、データを増やしたり減らしたりが簡単
  6. //ノード(値+次のノードへのポインタ)をつないでいく構造
  7.  
  8. //ノードの構造体(val と next の2つで1セット)
  9. typedef struct node{
  10. int val;
  11. struct node *next;
  12. }Node;
  13.  
  14. //head はリストの先頭を指す(絶対に見失わないこと)
  15. Node *head = NULL;
  16.  
  17. //ノードを1個作る(値xで初期化)
  18. Node* createN(int x){
  19. Node *p = (Node*)malloc(sizeof(Node));
  20. p->val = x;
  21. p->next = NULL; //末尾なので next はNULL
  22. return p;
  23. }
  24.  
  25. //n個の値でリストを初期化(演習1)
  26. void initL(int n){
  27. int x;
  28. scanf("%d", &x);
  29. head = createN(x); //最初のノード
  30. Node *p = head;
  31.  
  32. for(int i = 1; i < n; i++){
  33. scanf("%d", &x);
  34. p->next = createN(x); //次のノードをつなぐ
  35. p = p->next; //ポインタを進める
  36. }
  37. }
  38.  
  39. //リストを解放(freeL)
  40. void freeL(){
  41. Node *p;
  42. while(head != NULL){
  43. p = head->next; //次を覚えておく
  44. free(head); //今のノードを解放
  45. head = p; //次へ進む
  46. }
  47. }
  48.  
  49. //ノード1個を出力(NULLならNULLと出す)
  50. void printN(Node *a){
  51. if(a == NULL) printf("NULL\n");
  52. else printf("%d\n", a->val);
  53. }
  54.  
  55. //リスト全体を出力(先頭から順に)
  56. void printL(){
  57. Node *p = head;
  58. while(p != NULL){
  59. printf("%d ", p->val);
  60. p = p->next;
  61. }
  62. printf("\n");
  63. }
  64.  
  65. //n番目のノードを返す(1番目がhead)
  66. Node* getN(int n){
  67. Node *p = head;
  68. for(int i = 1; i < n; i++){
  69. p = p->next;
  70. }
  71. return p;
  72. }
  73.  
  74. //要素数を数える(countL)
  75. int countL(){
  76. int ret = 0;
  77. Node *p = head;
  78. while(p != NULL){
  79. ret++;
  80. p = p->next;
  81. }
  82. return ret;
  83. }
  84.  
  85. //値xを探す(searchX)→ 見つかったノード or NULL
  86. Node* searchX(int x){
  87. for(Node *p = head; p != NULL; p = p->next){
  88. if(p->val == x) return p;
  89. }
  90. return NULL;
  91. }
  92.  
  93. //先頭に挿入(insHead)
  94. void insHead(int x){
  95. Node *p = createN(x);
  96. p->next = head; //今の先頭を後ろにつなぐ
  97. head = p; //新しい先頭
  98. }
  99.  
  100. //先頭を削除(delHead)
  101. void delHead(){
  102. Node *p = head;
  103. head = head->next; //次を先頭にする
  104. free(p);
  105. }
  106.  
  107. //末尾に挿入(insTail)
  108. void insTail(int x){
  109. Node *p = head;
  110. while(p->next != NULL){
  111. p = p->next;
  112. }
  113. p->next = createN(x);
  114. }
  115.  
  116. //末尾を削除(delTail)
  117. void delTail(){
  118. Node *p = head;
  119. while(p->next->next != NULL){
  120. p = p->next;
  121. }
  122. free(p->next);
  123. p->next = NULL;
  124. }
  125.  
  126. //中間に挿入(n番目の後に挿入)
  127. void insMiddle(int n, int x){
  128. Node *p = head;
  129. for(int i = 1; i < n; i++){
  130. p = p->next;
  131. }
  132. Node *q = createN(x);
  133. q->next = p->next;
  134. p->next = q;
  135. }
  136.  
  137. //中間を削除(n番目を削除)
  138. void delMiddle(int n){
  139. Node *p = head;
  140. for(int i = 1; i < n-1; i++){
  141. p = p->next;
  142. }
  143. Node *q = p->next;
  144. p->next = q->next;
  145. free(q);
  146. }
  147.  
  148. int main(void){
  149. int n;
  150. scanf("%d", &n);
  151.  
  152. initL(n); //n個で初期化
  153. printL(); //確認用
  154.  
  155. //ここに好きな操作を追加して試す
  156. //insHead(100);
  157. //insTail(200);
  158. //insMiddle(2, 999);
  159. //delHead();
  160. //delTail();
  161. //delMiddle(3);
  162.  
  163. printL();
  164.  
  165. freeL();
  166. return 0;
  167. }
  168.  
Success #stdin #stdout 0s 5320KB
stdin
5
10 20 30 40 50
stdout
10 20 30 40 50 
10 20 30 40 50