线性表和堆栈的实现

1.1 概念

“线性表(Linear List)”:由同类型数据元素构成有序序列的线性结构

  • 表中元素的个数称为线性表的长度
  • 线性表没有元素,称为空表
  • 表起始位置称表头,表结束位置称为表尾。

1.2 抽象数据类型描述

类型名称:线性表(List)
数据对象集:线性表是n()个元素构成的有序序列
操作集:线性表,整数i表示位置,元素,线性表基本操作主要有:

  1. List MakeEmpty():初始化一个空线性表L;
  2. Find():根据位序K,返回相应元素;
  3. 在线性表L中查找X的第一次出现位置;
  4. 在位序i前插入一个新元素X;
  5. 删除指定位序i的元素;
  6. 返回线性表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

  1. Stack CreateStack( int MaxSize):生成空堆栈,其最大长度为MaxSize;
  2. int isFul(StackS,int MaxSize):判断堆栈S是否已满
  3. void Push(Stack S, Element Type item):将元素item压入堆栈
  4. int IsEmpty(StackS):判断堆栈S是否为空;
  5. 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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值