02_线性表

一、描述线性表

在一个非空有限的集合中,存在唯一一个被称为“第一个”的数据元素,和唯一一个被称为“最后一个”的数据元素,除第一个之外,每个元素只有一个直接前驱,除最后一个外,每个元素只有一个直接后驱。

二、线性表基本运算

构造一个空线性表、判断是否为空、返回线性表中元素的个数,返回线性表中索引 i 的数据元素,排序,拆分,清空,销毁等

三、线性表顺序存储

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 #include <stdlib.h>
  4 
  5 
  6 //定义一个数据类型 Array 来模拟数组 
  7 struct Array
  8 {
  9     int *pBase;// 数组的首地址
 10     int len;//数组的长度
 11     int count;//数组元素个数 
 12 };
 13 
 14 void initArr(struct Array *pArr,int length);
 15 void showArray(struct Array *pArr);
 16 bool arr_Isempty(struct Array *pArr);
 17 bool arr_full(struct Array* pArr);
 18 //插入元素
 19 bool append_arr(struct Array* pArr,int val); 
 20 bool insert_arr(struct Array* pArr,int pos,int val);
 21 bool delete_arr(struct Array *pArr,int pos);
 22 void inversion_arr(struct Array* pArr);
 23 int main(void)
 24 {
 25     //定义一个结构体变量
 26     struct Array arr;
 27     //初始化
 28     initArr(&arr,6);
 29     //打印数组元素
 30     //showArray(&arr);
 31     //传入数组元素 
 32     append_arr(&arr,1); 
 33     append_arr(&arr,2); 
 34     append_arr(&arr,3); 
 35     append_arr(&arr,4);
 36     append_arr(&arr,5);
 37 //    append_arr(&arr,6);
 38     
 39     insert_arr(&arr,2,88); //1 88 2 3 4 5
 40     delete_arr(&arr,2); 
 41     showArray(&arr);
 42     printf("\n倒置:\n");
 43     inversion_arr(&arr);
 44     showArray(&arr);
 45 }
 46 
 47 //初始化数组,分配空间,指定长度和元素总个数 
 48 void initArr(struct Array *pArr,int length)
 49 {
 50     pArr->pBase = (int *)malloc(sizeof(struct Array) * length);
 51     if(pArr->pBase == NULL)
 52     {
 53         printf("内存分配失败!");
 54         return;
 55     }
 56     else
 57     {
 58         pArr->len = length;
 59         pArr->count = 0;
 60     }
 61     return ; 
 62 }
 63 //判断数组是否为空
 64 bool arr_Isempty(struct Array *pArr)
 65 {
 66     //如果数组总个数为空,返回true 
 67     if(0 == pArr->count)
 68     {
 69         return true;
 70     }
 71     else
 72     {
 73         return false;
 74     }
 75 }
 76 bool arr_full(struct Array* pArr)
 77 {
 78     if(pArr->count == pArr->len)
 79     {
 80         printf("已满\n");
 81         return true;
 82     }
 83     else
 84     {
 85         return false; 
 86     }
 87 }
 88 //循环打印数组
 89 void showArray(struct Array *pArr)
 90 {
 91     //首先判断数组元素是否为空
 92     if(arr_Isempty(pArr))
 93     {
 94         printf("数组元素为空!");
 95         return; 
 96     } 
 97     else
 98     {
 99         //循环打印输出
100         for(int i = 0;i < pArr->count;i++)
101         {
102             printf("%d    ",pArr->pBase[i]);
103         }
104     }
105     
106 }
107 
108 bool append_arr(struct Array* pArr,int val)
109 {
110     //判断数组是否已满
111     if (arr_full(pArr))
112     {
113         printf("数组已满,插入失败!"); 
114         return false;
115     } 
116     pArr->pBase[pArr->count] = val;
117     pArr->count++;
118 }
119 //插入元素 
120 bool insert_arr(struct Array* pArr,int pos,int val)
121 {
122     if(arr_full(pArr)){
123         return false;
124     }
125     if(pos < 1 || pos > pArr->count + 1){
126         return false;
127     }
128     
129     int i ;
130     for (i=pArr->count-1;i >= pos - 1; --i)
131     {
132         pArr->pBase[i+1] = pArr->pBase[i];
133     }
134     pArr->pBase[pos-1] = val;
135     pArr->count++;
136     return true;
137 }
138 // 1 88 2 3 4 5   2
139 bool delete_arr(struct Array *pArr,int pos)
140 {
141     if(arr_Isempty(pArr))
142     {
143         printf("数组为空,删除元素失败!");
144         return false;
145     }
146     if(pos > pArr->count || pos < 1)
147     {
148         printf("范围错误!");
149         return false;
150     }
151     int i;
152     for(i = pos;i < pArr->count;i++)
153     {
154         //printf("\n pArr->pBase[i] : %d\n",pArr->pBase[i]);
155         pArr->pBase[i-1] = pArr->pBase[i];
156     }
157     pArr->count -- ;
158     return true;
159 }
160 
161 void inversion_arr(struct Array* pArr)
162 {
163     int i = 0;
164     int j = pArr->count -1 ;//数组是从开始的 
165     int t = 0;
166     while(i < j)
167     {
168         t = pArr->pBase[i];
169     //    printf("t : %d\n",t);
170     //    printf("j : %d\n",j);
171         pArr->pBase[i] = pArr->pBase[j];
172         pArr->pBase[j] = t;
173     //    printf(" pBase[i] : %d\n",pArr->pBase[j]);
174         ++i;
175         --j;
176     }
177 }
178  

 

四、线性表链式存储

  1 #include<stdio.h>
  2 #include<malloc.h>
  3 #include<stdlib.h>
  4 
  5 //定义了一个 数据类型 
  6 typedef struct Node
  7 {
  8     int data; //数据域 
  9     struct Node* pNext;//指针域 
 10 }NODE,* PNODE;//NODE == struct Node ; PNODE = struct Node*
 11 
 12 PNODE create_list(void);
 13 void traverse_list(PNODE pHead);
 14 bool isempty_list(PNODE pHead);
 15 int length_list(PNODE pHead);
 16 bool insert_list(PNODE pHead,int pos,int val);
 17 bool delete_list(PNODE pHead,int pos,int *val);
 18 void sort_list(PNODE pHead);
 19 
 20 int main(void)
 21 {
 22     int val; 
 23     PNODE pHead = NULL;//struct Node* pHead 指向Node的指针变量
 24     pHead = create_list();//创建一个非循环单链表,单链表头节点地址返回给pHead 
 25     traverse_list(pHead);
 26 /*    if(isempty_list(pHead))
 27     {
 28         printf("链表为空!\n");
 29     }else
 30     {
 31         printf("链表不为空!\n");
 32     }
 33 */    
 34     printf("链表的长度:%d.\n",length_list(pHead));
 35     //insert_list(pHead,1,5); 在首结点前插入
 36 //    insert_list(pHead,5,5);   当要插入的结点大于总长度的时候 
 37 //    printf("插入元素后:\n");
 38 //    traverse_list(pHead);
 39 //    printf("删除元素后:\n");
 40 //    delete_list(pHead,1,&val);    
 41 //    printf("被删除的元素为:%d\n",val);
 42     //traverse_list(pHead);
 43     sort_list(pHead);
 44     traverse_list(pHead);
 45     return 0;
 46 }
 47 
 48 //创建一个链表 
 49 PNODE create_list(void)
 50 {
 51     int len;//链表的长度
 52     int i;
 53     int val;//临时存储数据 
 54     printf("请输入你需要的链表长度len =\n") ;
 55     scanf("%d",&len);
 56     PNODE pHead = (PNODE)malloc(sizeof(NODE));
 57     if(NULL == pHead)
 58     {
 59         printf("内存分配失败!");
 60         exit(-1); 
 61     } 
 62     
 63     PNODE pTail = pHead;
 64     pTail->pNext = NULL;
 65     for(i = 0;i < len;i++)
 66     {
 67         printf("请输入要存储的数据:\n");
 68         scanf("%d",&val);
 69         //创建一个个链表
 70         PNODE pNew = (PNODE)malloc(sizeof(NODE));
 71         if(NULL == pNew)
 72         {
 73             printf("pNew内存分配失败!");
 74             exit(-1);
 75         }
 76         pNew->data = val; 
 77         
 78         pTail->pNext = pNew;//把新结点挂在尾结点的后面 
 79         pNew->pNext = NULL;//新结点变成尾结点了 
 80         pTail = pNew;//然后pTail指向新结点变成尾结点 
 81     }
 82      
 83      return pHead;
 84 }
 85 
 86 //遍历链表 
 87 void traverse_list(PNODE pHead)
 88 {
 89     PNODE p = pHead->pNext; // 让p指向首结点
 90     while(NULL != p)
 91     {
 92         printf("%d\t",p->data);
 93         p = p->pNext; //p往后移    
 94     } 
 95     printf("\n");
 96     return;
 97 }
 98 bool isempty_list(PNODE pHead)
 99 {
100     if(NULL == pHead || pHead->pNext == NULL)
101     {
102         return true;
103     }
104     else
105     {
106         return false;
107     }
108 }
109 
110 int length_list(PNODE pHead)
111 {
112     int i = 0;
113     PNODE p = pHead->pNext;
114     while (p != NULL)
115     {
116         i++;
117         p = p->pNext;
118     }
119     return i;
120 }
121 
122 //插入 
123 bool insert_list(PNODE pHead,int pos,int val)
124 {
125     int i ;
126     PNODE pT = pHead;
127     PNODE pTmp = (PNODE)malloc(sizeof(NODE));
128     PNODE pNew = (PNODE)malloc(sizeof(NODE));
129     pNew->data = val;
130     
131     if(pos == 1)
132     {
133         for(i = 0;i < pos-1;i++)
134         {
135             pTmp = pT->pNext;//第一个结点 
136             pNew = pTmp->pNext; 
137             pTmp->pNext = pNew;
138         }
139     } 
140     else if(pos > length_list(pHead))
141     {
142         for(i = 0;i < length_list(pHead) ;i++){
143             pT = pT->pNext;
144         }
145             pNew->pNext = pT->pNext;
146             pT->pNext = pNew;    
147     }
148     else
149     {
150         for(i = 0;i < pos -1;i++)
151         {
152             pT = pT->pNext;
153         }
154 
155         pNew->pNext = pT->pNext;
156         pT->pNext = pNew;
157     }
158     
159 
160     return true;
161 }
162 //删除元素 
163 bool delete_list(PNODE pHead,int pos,int *val)
164 {
165     int i;
166     if(pos < 1 || pos > length_list(pHead))
167     {
168         printf("\n位置超出范围,删除失败!\n");
169         exit(-1);    
170     } 
171     PNODE pNode = (PNODE)malloc(sizeof(NODE));
172     PNODE pTmp = pHead;
173     //printf("\n pos : %d",pos);
174     for(i = 0;i < pos -1;i++)
175     {
176         pTmp = pTmp->pNext;//此时pTmp指向的是首结点
177         pNode = pTmp->pNext;//此时pTmp指向的是第二个结点,赋给pNode,pNode指向的就是第二个结点
178         pTmp->pNext = pNode->pNext;//此时获取到的是第三个结点,赋给了pTmp,pTmp指向了第三个结点 
179         *val = pNode->data;
180         printf("\n第%d结点的元素是%d.\n",pos,pNode->data);
181         free(pNode);
182     }
183 }
184 
185 void sort_list(PNODE pHead)
186 {
187     //从狭义的讲 算法和存储结构有关
188     //广义讲 算法和存储结构无关 
189     int i,j,t;
190     PNODE p,q;
191     int len = length_list(pHead);
192     for(i = 0,p = pHead->pNext;i < len -1;i++,p = p->pNext)
193     {
194         for(j = i+1,q = p->pNext;j < len;j++ ,q=q->pNext)
195         {
196             if(p->data > q->data)//类似数组中的 a[i] > a[j]
197             {
198                 t = p->data;//类似数组中的 t= a[i]
199                 p->data = q->data;//类似数组中的 a[i]= a[j]
200                 q->data = t;//类似数组中的 a[j]= t
201             }
202         }
203     } 
204 }

五、顺序表和链表的比较

1.如果线性表需要频繁查找,很少进行插入和删除,宜采用顺序表结构,反之,采用链表

2.线性表个数不能确定的情况下,链表优于顺序表。

 

posted @ 2018-01-21 01:30  短毛兔  阅读(174)  评论(0编辑  收藏  举报