1.1 概念
“线性表(Linear List)”:由同类型数据元素构成有序序列的线性结构
- 表中元素的个数称为线性表的长度
- 线性表没有元素,称为空表
- 表起始位置称表头,表结束位置称为表尾。
1.2 抽象数据类型描述
类型名称:线性表(List)
数据对象集:线性表是n()个元素构成的有序序列
操作集:线性表,整数i表示位置,元素,线性表基本操作主要有:
- List MakeEmpty():初始化一个空线性表L;
- Find():根据位序K,返回相应元素;
- 在线性表L中查找X的第一次出现位置;
- 在位序i前插入一个新元素X;
- 删除指定位序i的元素;
- 返回线性表L的长度n。
1.3 顺序存储形式
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
typedef struct LNode *List;
struct LNode
{
int Data[MAXSIZE];
int Last;
};
// 1. 初始化
List MakeEmpty()
{
List Ptrl; // 定义指针类型
Ptrl = (List)malloc(sizeof(struct LNode)); // 分配内存空间
Ptrl->Last = -1;
return Ptrl;
}
// 2. 查找
int Find(int x, List Ptrl)
{
int i = 0;
while(i <= Ptrl->Last && Ptrl->Data[i] != x) i ++; // 找到或者越界为止
if (i > Ptrl->Last) return -1; // 如果没有找到返回-1
else return i; // 找到后返回下标
}
// 3. 插入
List Insert(int x, int i, List Ptrl)
{
int j;
if (Ptrl->Last == MAXSIZE - 1)
{
printf("线性表已满\n");
return Ptrl;
}
if (i < 1 || i > Ptrl->Last + 2) // 插入的位置最小是第一个位置,最大是最后一个位置
{
printf("位置不合法\n");
return Ptrl;
}
for (j = Ptrl->Last; j >= i - 1; -- j)
{
Ptrl->Data[j + 1] = Ptrl->Data[j];
}
Ptrl->Data[i - 1] = x; // 将新元素插入
Ptrl->Last++; // Last指向最后一个位置
return Ptrl;
// 这个i如果不是插入第几个,而是角标的话,插入操作会容易理解很多
}
// 4. 删除
void Delete(int i, List Ptrl)
{
int j;
if (i < 1 || i > Ptrl->Last + 1)
{
printf("不存在%d这个位置上的值\n", i);
return;
}
for(j = i; j < Ptrl->Last; ++ j)
{
Ptrl->Data[j-1] = Ptrl->Data[j];
}
Ptrl->Last--;
printf("删除操作成功\n");
}
// 5. 返回长度
void retLength(List Ptrl)
{
printf("线性表的长度为%d。\n", Ptrl->Last + 1);
}
// 6. 展示线性表
void show(List Ptrl)
{
if (Ptrl->Last < 0)
{
printf("当前线性表为空\n");
return;
}
for(int i = 0; i <= Ptrl->Last; ++ i)
{
printf("%d ", Ptrl->Data[i]);
}
printf("\n");
return;
}
// 7. 菜单
void menu()
{
printf("-------------------------\n");
printf("Do something you want!\n");
printf("1. 查找\n");
printf("2. 插入\n");
printf("3. 删除\n");
printf("4. 查看线性表长度\n");
printf("5. 查看当前线性表\n");
printf("6. 退出\n");
printf("请选择您要进行的操作:\n");
}
// 初始化
int findFig = -1;
int findRes = -1;
int insertFig = -1;
int insertAddr = -1;
int deleteAddr = -1;
int pos = -1;
int k = 1;
int main()
{
List Ptrl = MakeEmpty();
while (k)
{
menu();
scanf("%d", &pos);
switch(pos)
{
case 1: // 查找
printf("你想要找的值是?\n");
scanf("%d", &findFig);
findRes = Find(findFig, Ptrl);
printf("你要找的值的索引是%d\n", findRes);
break;
case 2:
printf("你想要插入的值是?\n");
scanf("%d", &insertFig);
printf("你想要插入的位置是?\n");
scanf("%d", &insertAddr);
Insert(insertFig, insertAddr, Ptrl);
break;
case 3:
printf("你想要删除的位置是?\n");
scanf("%d", &deleteAddr);
Delete(deleteAddr, Ptrl);
break;
case 4:
retLength(Ptrl);
break;
case 5:
show(Ptrl);
break;
default:
k = 0;
break;
}
}
Ptrl = NULL;
free(Ptrl);
return 0;
}
1.4 链表形式
#include <stdio.h>
#include <stdlib.h>
// 定义
typedef struct LNODE *List;
struct LNODE
{
int data;
List Next;
};
// 1. 求表长
void Length(List Ptrl)
{
List p = Ptrl;
int ret = 0;
while (p)
{
p = p->Next;
ret++;
}
printf("线性表的长度为%d\n",ret);
}
// 2. 按位查找
List FindK(int k, List Ptrl)
{
List P = Ptrl;
int i = 1;
while (i < k && P != NULL)
{
P = P->Next;
i++;
}
if (i == k) return P; // 找到第k个,返回指针
else return NULL; // 没有找到,返回NULL
}
// 3. 按值查找
int Find(int x, List Ptrl)
{
List P = Ptrl;
int i = 1;
while (P != NULL && P->data != x)
{
P->Next = NULL;
i++;
}
return i;
}
// 4. 插入
List Insert(int x, int i, List Ptrl)
{
List p, s;
if (i == 1)
{
s = (List)malloc(sizeof(struct LNODE));
s->data = x;
s->Next = Ptrl;
return s;
}
p = FindK(i - 1, Ptrl);
if (p == NULL)
{
printf("插入位置错误\n");
return NULL;
}
else
{
s = (List)malloc(sizeof(struct LNODE));
s->data = x;
s->Next = p->Next;
p->Next = s;
return Ptrl;
}
}
// 5. 删除
List deleteNode(int i, List Ptrl)
{
List p, s;
if (i == 1)
{
s = Ptrl;
if (Ptrl != NULL) Ptrl = Ptrl->Next;
else return NULL;
free(s);
return Ptrl;
}
p = FindK(i - 1, Ptrl);
if (p == NULL)
{
printf("节点%d不存在\n", i - 1);
return NULL;
}
else if (p->Next == NULL)
{
printf("节点%d不存在\n", i);
return NULL;
}
else
{
s = p->Next;
p->Next = s->Next;
free(s);
return Ptrl;
}
}
// 6. 初始化
List CreateList()
{
return NULL;
}
// 7. 展示线性表
void Show(List Ptrl)
{
List p = Ptrl;
int i = 1;
if (p == NULL)
{
printf("该线性表为空\n");
}
while (p)
{
printf("第%d个节点:", i++);
printf("%d\n",p->data);
p = p->Next;
}
return;
}
// 8. 菜单
void menu()
{
printf("-------------------------\n");
printf("Do something you want!\n");
printf("1. 查找\n");
printf("2. 插入\n");
printf("3. 删除\n");
printf("4. 查看线性表长度\n");
printf("5. 查看当前线性表\n");
printf("6. 退出\n");
printf("请选择您要进行的操作:\n");
}
// 全局变量
int k = 1;
int findRes = -1;
int findFig = -1;
int insertFig = -1;
int insertAddr = -1;
int deleteAddr = -1;
int pos = -1;
int main()
{
List Ptrl = CreateList();
while (k)
{
menu();
pos = 0;
scanf("%d", &pos);
if (pos > 6 || pos < 1)
{
printf("输入了什么玩意!\n");
continue;
}
switch (pos)
{
case 1: // 查找
printf("你想要找的值是?\n");
scanf("%d", &findFig);
findRes = Find(findFig, Ptrl);
printf("你要找的值是第%d个节点\n", findRes);
break;
case 2:
printf("你想要插入的值是?\n");
scanf("%d", &insertFig);
printf("你想要插入的位置是?\n");
scanf("%d", &insertAddr);
Ptrl = Insert(insertFig, insertAddr, Ptrl);
break;
case 3:
printf("你想要删除的位置是?\n");
scanf("%d", &deleteAddr);
Ptrl = deleteNode(deleteAddr, Ptrl);
break;
case 4:
Length(Ptrl);
break;
case 5:
Show(Ptrl);
break;
default:
k = 0;
break;
}
}
Ptrl = NULL;
free(Ptrl);
return 0;
}
2堆栈
堆栈的抽象数据类型描述
类型名称:堆栈(Stack)
数据对象集:一个有0个或多个元素的有穷线性表。
操作集:长度为MaxSize的堆栈SeStack,堆元素itemeElementType
- Stack CreateStack( int MaxSize):生成空堆栈,其最大长度为MaxSize;
- int isFul(StackS,int MaxSize):判断堆栈S是否已满
- void Push(Stack S, Element Type item):将元素item压入堆栈
- int IsEmpty(StackS):判断堆栈S是否为空;
- ElementType Pop(StackS) 删除并返回栈顶元素
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 20
typedef struct Stack *Stk;
struct Stack
{
char Data[MAX_SIZE];
int Top;
};
// 1. 入栈
void Push(Stk PtrS, char item)
{
if (PtrS->Top == MAX_SIZE - 1)
{
printf("堆栈已满\n");
}
else
{
PtrS->Data[++(PtrS->Top)] = item;
}
return;
}
// 2. 出栈
char Pop(Stk PtrS)
{
if (PtrS->Top == -1)
{
printf("堆栈空\n");
return 'X';
}
else
{
return PtrS->Data[PtrS->Top--];
}
return 0;
}
// 3. 判断堆栈是否已满
int IsFull(Stk PtrS)
{
if (PtrS->Top == MAX_SIZE - 1)
return 1;
}
// 4. 判断是否为空
int IsEmpty(Stck PtrS)
{
if (PtrS->Top == -1)
return 1;
}
int main()
{
Stk s; // 定义指针类型
s = (Stk)malloc(sizeof(struct Stack)); // 分配内存空间
s->Top = -1;
char a, b;
Push(s, 'a');
Push(s, 'b');
a = Pop(s);
b = Pop(s);
printf("%c %c\n", a, b);
return 0;
}