线性表

1.1线性表(List)及实现

1.1.1线性表的定义

  • 由同类型数据元素构成有序序列的线性结构
  • 表中元素个数成为L的表长
  • 表中无元素时,称为空表
  • 表的起始位置称为表头,结束位置称为表尾

1.1.2线性表的存储实现

数组和链表的空间分配情况:

  • 数组在静态存储分配情形下,存储元素数量受限制,动态存储分配情形下,虽然存储空间可以扩充,但需要移动大量元素,导致操作效率降低,而且如果内存中没有更大块连续存储空间将导致分配失败;即数组从栈中分配空间,,对于程序员方便快速,但自由度小。
  • 链表存储的节点空间只在需要的时候申请分配,只要内存中有空间就可以分配,操作比较灵活高效;即链表从堆中分配空间, 自由度大但申请管理比较麻烦。

线性表的基本操作:

(1)List MakeEmpty():初始化一个空线性表L

(2)ElementType FindKth(int k,List L):根据位置k,查找返回位置的元素

(3)int Find(ElementType X,List L):在线性表L中查找X第一次出现的位置

(4)void Insert(ElementType X,int i,List L):在i位置前插入元素X

(5)void Delete(int i,List L):删除i位置的元素

(6)int Length(List L):返回线性表L的长度

1.1.2.1线性表的顺序存储实现

 1 #define MAXSIZE 100//定义Data的最大值
 2 typedef int ElementType;
 3 typedef struct LNode *List;
 4 struct LNode
 5 {
 6     ElementType Data[MAXSIZE];
 7     int Last;//定义线性表的最后一个元素的下标或者记录表长的变量也可
 8 };
 9 List L;
10 
11 //初始化
12 List MakeEmpty() {
13     List L;
14     L = (List)malloc(sizeof(LNode));//申请一个线性表的空间
15     L->Last = -1;
16     return L;
17 }
18 
19 //按值查找
20 int Find(ElementType X, List L) {
21     int i = 0;
22     while (i <= L->Last&&L->Data[i] != X) {
23         i++;
24     }
25     if (L->Last < i) {
26         return -1;//没找到,是i>last的时候跳出的
27     }
28     else
29         return i;//找到了,是相等的时候跳出的
30 }
31 
32 //插入
33 void Insert(ElementType X, int i, List L) {
34     int j;
35     if (L->Last == MAXSIZE - 1) {
36         printf("表满");
37         return;
38     }
39     if (i < 0 || L->Last + 1<i) {
40         printf("位置不合法");
41         return;
42     }
43     for (j = L->Last; j >= i; j--) {
44         L->Data[j + 1] = L->Data[j];//从后往前
45     }
46     L->Data[i] = X;
47     L->Last++;//last仍然指向最后一个元素
48         return49 }
50 
51 //删除
52 void Delete(int i, List L) {
53     int j;
54     if (i<0 || i>L->Last) {
55         printf("L->Data[%d]不存在元素",i);
56         return;
57     }
58     for (j = i; j <= L->Last; j++) {
59         L->Data[j] = L->Data[j+1];
60     }
61     L->Last--;
62         return63 }
64 
65 //按序查找 顺序存储最大的优点
66 ElementType FindKth(int k, List L) {
67     if (k<0 || k>L->Last) {
68         printf("L->Data[%d]不存在元素", k);
69         return 0;
70     }
71     return L->Data[k];
72 }
73 
74 //表长
75 int Length(List L) {
76     return L->Last + 1;
77 }    

1.1.2.2线性表的链表存储实现

  1 typedef int ElementType;
  2 typedef struct LNode *List;
  3 struct LNode
  4 {
  5     ElementType Data;//数据域
  6     List Next;//下一个链表的地址
  7 };
  8 List L;//L既是单链表的名字又是头指针的名字
  9 
 10 //初始化
 11 //建立一个带有头结点的链表
 12 List MakeEmpty1() {
 13     List L = (List)malloc(sizeof(LNode));//申请头结点
 14     if (L == NULL) {
 15         printf("申请空间失败!");
 16     }
 17     else {
 18         L->Data = 100;
 19         L->Next = NULL;//头结点指向NULL
 20     }
 21     return L;
 22 }
 23 
 24 //建立不带头结点的链表
 25 List MakeEmpty2() {
 26     List L = NULL;//头指针不指向任何结点
 27     return L;
 28 }
 29 
 30 //表长
 31 int Length(List L) {
 32     List p = L;//定义一个List类型的指针,将其初始化为头指针
 33     int len = 0;
 34     while (p) {
 35         p = p->Next;
 36         len++;
 37     }
 38     return len;
 39 }
 40 
 41 //按序查找 
 42 List FindKth(int k,List L) {
 43     List p = L;
 44     int i = 1;//链表从1开始
 45     while (p&&i<k)
 46     {
 47         p = p->Next;
 48         i++;
 49     }
 50     if (i == k)
 51         return p;//返回结点
 52     else
 53         return NULL;
 54 }
 55 
 56 //按值查找
 57 List Find(ElementType X, List L) {
 58     List p = L;
 59     while (p&&p->Data != X) {
 60         p = p->Next;
 61     }
 62     //找到了返回p
 63     //未找到,此时p是NULL
 64     return p;
 65 }
 66 
 67 //插入新节点
 68 List Insert(ElementType X, int i, List L) {
 69     List s = (List)malloc(sizeof(LNode));//申请一个新节点
 70     s->Data = X;
 71     //新节点插入在表头
 72     if (i == 1) {
 73         s->Next = L;
 74         return s;//因为此时s就是第一个节点
 75     }
 76     //插入的节点在中间 p表示第i-1位的节点
 77     List p = FindKth(i - 1, L);
 78     if (!p) {//如果第i个节点不存在
 79         printf("节点错误");
 80             return NULL;
 81     }
 82     else {
 83         s->Data = X;
 84         s->Next = p->Next;
 85         p->Next = s;
 86         return L;
 87     }
 88 }
 89 
 90 //删除
 91 List Delete(int i, List L) {
 92     List s, p;
 93     //如果删除头结点
 94     if (i == 1) {
 95         s = L;
 96         if (L) {//如果不为空
 97             L = L->Next;//现在头结点变成原来的第二个节点
 98         }
 99         else
100             return NULL;
101         free(s);
102         return L;
103     }
104     p = FindKth(i - 1, L);
105     if (!p || !(p->Next)) {//如果i-1或者i不存在
106         printf("节点错误");
107         return NULL;
108     }
109     s = p->Next;
110     p->Next = s->Next;
111     free(s);
112     return L;
113 }
114 
115 //输出链表元素
116 void Print(List L) {
117     List t;
118     int flag = 1;
119     printf("当前列表为:");
120     for (t = L; t; t = t->Next) {
121         printf("%d ", t->Data);
122         flag = 0;
123     }
124     if (flag)
125         printf("NULL");
126     printf("
");
127 }
作者:PennyXia
         
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/PennyXia/p/12590177.html