最近有点偷懒,加上期末考试临近,已经有半个多月没发过博客了,这几天学习了一点数据结构顺序表的东西,就整理一些顺序表的基本操作吧。
先写一个包含需要进行的操作的头文件,在测试代码和执行代码中就可以引入这个头文件:
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef _SEQLIST_H_
#define _SEQLIST_H_
#include<assert.h>
#include<stdio.h>
#include<string.h>
#include<windows.h>
#define MAX 100
typedef int DataType; //数据类型
typedef struct SeqList
{
int data[MAX]; //数据
int sz; //数据个数
}SeqList,*pSeqList;
void InitSeqList(pSeqList pSeq); //初始化顺序表
void PrintSeqList(pSeqList pSeq); //打印当前顺序表
int Empty(pSeqList pSeq); //判断顺序表是否为空
int Size(pSeqList pSeq); //返回顺序表达的大小
void PushBack(pSeqList pSeq,DataType d); //从顺序表尾部插入元素
void PopBack(pSeqList pSeq); //从顺序表尾部删除元素
void PushFront(pSeqList pSeq,DataType d); //从顺序表头部插入元素
void PopFront(pSeqList pSeq); //从顺序表头部删除元素
int Find(pSeqList pSeq, DataType d); //查找指定元素的下标
void Insert(pSeqList pSeq, int pos, DataType d); //指定位置插入元素
void Erase(pSeqList pSeq, int pos); //删除指定位置的元素
void Remove(pSeqList pSeq, DataType d); //删除指定元素
void BubbleSort(pSeqList pSeq); //对顺序表元素进行冒泡法冒泡
首先,建立一个顺序表:
void InitSeqList(pSeqList pSeq) //初始化顺序表
{
assert(pSeq!= NULL);
pSeq->sz = 0;
memset(pSeq->data, 0, sizeof(pSeq->data));
}
判断这个顺序表是否为空,若不为空,返回其大小:
int Empty(pSeqList pSeq) //判断顺序表是否为空
{
assert(pSeq != NULL);
if (pSeq->sz == 0)
{
printf(" 顺序表为空\n");
}
else
{
printf(" 顺序表不为空,其大小为:%d\n", pSeq->sz);
}
return 0;
}
打印顺序表:
void PrintSeqList(pSeqList pSeq)
{
int i = 0;
assert(pSeq != NULL);
for (i = 0; i < pSeq->sz; i++)
{
printf(" %d", pSeq->data[i]);
}
printf("\n");
}
先测试一下判断表空和打印顺序表的代码:
TextSize()
{
SeqList seq;
InitSeqList(&seq);
Empty(&seq); //应输出:顺序表为空
PushFront(&seq, 1);
PushFront(&seq, 2);
PushFront(&seq, 3);
PushFront(&seq, 4);
PushFront(&seq, 5);
PrintSeqList(&seq); //5 4 3 2 1
Empty(&seq); //应输出:顺序表不为空,其大小为:5
}
显示结果如下:
与代码注释中预测的结果一致。
尾插:
void PushBack(pSeqList pSeq, DataType d) //尾部插入
{
assert(pSeq != NULL);
if (pSeq->sz == MAX)
{
printf(" 表满,无法插入!");
return;
}
pSeq->data[pSeq->sz] = d;
pSeq->sz++;
}
尾删:
void PopBack(pSeqList pSeq) //尾部删除
{
assert(pSeq != NULL);
if (pSeq->sz==0)
{
printf(" 表为空,无法删除!");
return;
}
pSeq->sz--;
}
测试一下尾部插入删除操作的结果:
TextBack()
{
SeqList seq;
InitSeqList(&seq);
PushBack(&seq, 1);
PushBack(&seq, 2);
PushBack(&seq, 3);
PushBack(&seq, 4);
PushBack(&seq, 5);
PrintSeqList(&seq); //1 2 3 4 5
PopBack(&seq);
PrintSeqList(&seq); //1 2 3 4
PopBack(&seq);
PrintSeqList(&seq); //1 2 3
}
结果如下:
和在代码注释中预想的结果一样。’
头部插入元素:
void PushFront(pSeqList pSeq, DataType d) //头部插入
{
int i = 0;
assert(pSeq != NULL);
if (pSeq->sz == MAX)
{
printf(" 表满,无法插入!");
return;
}
for (i = pSeq->sz; i >= 0;i--)
{
pSeq->data[i+1] = pSeq->data[i];
}
pSeq->data[0]=d;
pSeq->sz++;
}
头部删除元素:
void PopFront(pSeqList pSeq) //头部删除
{
int i = 0;
assert(pSeq != NULL);
if (pSeq->sz == 0)
{
printf(" 表为空,无法删除!");
return;
}
for (i = 0; i <= pSeq->sz; i++)
{
pSeq->data[i] = pSeq->data[i+1];
}
pSeq->sz--;
}
测试一下头部插入删除操作的结果:
TextFront()
{
SeqList seq;
InitSeqList(&seq);
PushFront(&seq, 1);
PushFront(&seq, 2);
PushFront(&seq, 3);
PushFront(&seq, 4);
PushFront(&seq, 5);
PrintSeqList(&seq); //5 4 3 2 1
PopFront(&seq);
PrintSeqList(&seq); //4 3 2 1
PopFront(&seq);
PrintSeqList(&seq); //3 2 1
}
结果如下:
与代码注释中预测的结果一致。
查找某个元素,返回其下标:
int Find(pSeqList pSeq, DataType d) //查找指定元素
{
int i = 0;
assert(pSeq != NULL);
for (i = 0; i <= pSeq->sz; i++)
{
if (d == pSeq->data[i])
{
printf(" %d的位置为:%d\n",d,i);
}
}
return 0;
}
测试一下:
TextFind()
{
SeqList seq;
InitSeqList(&seq);
PushFront(&seq, 1);
PushFront(&seq, 2);
PushFront(&seq, 3);
PushFront(&seq, 4);
PushFront(&seq, 5);
PushFront(&seq, 2);
PrintSeqList(&seq); //2 5 4 3 2 1
Find(&seq, 2); //2的位置为0
//2的位置为4
}
显示结果如下:
与代码注释中预测的结果一致。
指定位置插入:
void Insert(pSeqList pSeq, int pos, DataType d) //在指定位置插入元素
{
int i = 0;
assert(pSeq != NULL);
if ((pos<0) || (pos>pSeq->sz))
{
printf(" 该位置不存在\n");
return;
}
for (i = pSeq->sz; i >= pos; i--)
{
pSeq->data[i+1] = pSeq->data[i];
}
pSeq->data[pos] = d;
pSeq->sz++;
}
指定位置删除:
void Erase(pSeqList pSeq, int pos) //删除指定位置元素
{
int i = 0;
assert(pSeq != NULL);
if ((pos<0) || (pos>pSeq->sz-1))
{
printf(" 该位置不存在\n");
return;
}
for (i = pos; i <= pSeq->sz;i++)
{
pSeq->data[i] = pSeq->data[i + 1];
}
pSeq->sz--;
}
测试一下这两个代码:
TextInsert()
{
SeqList seq;
InitSeqList(&seq);
Erase(&seq, 0); //先在空表中删除一下,应该输出:该位置不存在
PushFront(&seq, 1);
PushFront(&seq, 2);
PushFront(&seq, 3);
PushFront(&seq, 4);
PushFront(&seq, 5);
PrintSeqList(&seq); //5 4 3 2 1
Insert(&seq, 1, 6); //在1位置插入数字6
PrintSeqList(&seq); //5 6 4 3 2 1
Insert(&seq, 8, 9); //在不存在的位置插入一个数字9,应该输出:该位置不存在!
Erase(&seq, 4); //删除4位置元素
PrintSeqList(&seq); //5 6 4 3 1
}
显示结果如下:
与代码注释中预测的结果一致。
删除指定数字:
void Remove(pSeqList pSeq, DataType d) //删除指定元素
{
int i = 0;
int pos = 0;
assert(pSeq != NULL);
if (pSeq->sz == 0)
{
printf(" 顺序表为空,无法删除!\n");
return;
}
if ((pos = Find(pSeq, d) != -1))
{
Erase(pSeq, pos+1);
}
}
测试一下这段代码:
TextRemove()
{
SeqList seq;
InitSeqList(&seq);
PushFront(&seq, 1);
PushFront(&seq, 2);
PushFront(&seq, 3);
PushFront(&seq, 4);
PushFront(&seq, 5);
PrintSeqList(&seq); //5 4 3 2 1
Remove(&seq, 3);
PrintSeqList(&seq); //5 4 2 1
}
显示结果如下:
与代码注释中预测的结果一致。
接下来是顺序表元素的冒泡排序操作:
在排序操作前,首先得写一个元素换位函数Swap:
Swap(DataType* p1,DataType* p2)
{
DataType tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
由大到小冒泡排序:
void BubbleSort(pSeqList pSeq)
{
DataType tmp = 0;
int i = 0;
int j = 0;
assert(pSeq != NULL);
for (i = 0; i < pSeq->sz-1; i++)
{
for (j = 0; j < pSeq->sz-i-1; j++)
{
if (pSeq->data[j] < pSeq->data[j + 1])
{
Swap(pSeq->data + j, pSeq->data + j + 1);
}
}
}
}
测试一下:
TextBubbleSort()
{
SeqList seq;
InitSeqList(&seq);
PushFront(&seq, 5);
PushFront(&seq, 8);
PushFront(&seq, 6);
PushFront(&seq, 2);
PushFront(&seq, 7);
PrintSeqList(&seq); //7 2 6 8 5
BubbleSort(&seq); //由大到小冒泡排序
PrintSeqList(&seq); //8 7 6 5 2
}
显示结果如下:
与代码注释中预测的结果一致。
顺序表的操作还有很多,由于刚刚接触这些,所以仅写一些皮毛,更多的操作以后再与大家分享。另外,欢迎大家指出本篇博客中的错误!