データ構造について話す-シーケンステーブル
コンパイル環境:私はVS2013を使用していますが、より高度なバージョンも可能です。
ヘッダーファイルcommon.hとseqlist.h、ソースファイルDatabase.cpp、ヘッダーファイルcommon.hは主にさまざまな共通ヘッダーファイルと関数交換関数の3つのファイルを作成し、ヘッダーファイルseqlist.hは主にさまざまな関数の関数宣言と関数アルゴリズムの順序テーブル。ソースファイルDatabase.cppには、主に関数呼び出しとユーザーインターフェイスが含まれています。
主な機能
0.終了1.テールインサート2.ヘッドインサート3.ディスプレイ4.テール削除5.ヘッド削除6.位置による挿入7.値による挿入8.位置による削除9.値による削除10.検索11.長さ12.容量13.並べ替え14.逆順15.クリア16.最初の検索17.最後の検索18.バイナリ検索19.すべて削除
ヘッダーファイルcommon.h
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//用于内存泄露的检测
#include <vld.h>
#define ElemType int
void Swap(ElemType *a, ElemType *b)
{
ElemType tmp = *a;
*a = *b;
*b = tmp;
}
#endif /*_COMMON_H_*/
ヘッダーファイルseqlist.h
#ifndef _SEQLIST_H_
#define _SQLIST_H_
#include "common.h"
#define SEQLIST_DEFAULT_SIZE 8
//定义顺序表的结构
typedef struct SeqList
{
ElemType *base;
size_t capacity;
size_t size;
}SeqList;
void SeqListInit(SeqList *plist);
void SeqListDestroy(SeqList *plist);
void SeqListPushBack(SeqList *plist, ElemType x);
void SeqListPushFront(SeqList *plist, ElemType x);
void SeqListShow(SeqList *plist);
size_t SeqListLength(SeqList *plist);
void SeqListPopBack(SeqList *plist);
void SeqListPopFront(SeqList *plist);
void SeqListClear(SeqList *plist);
bool SeqListInsertByPos(SeqList *plist, int pos, ElemType x);
void SeqListSort(SeqList *plist);
size_t SeqListCapacity(SeqList *plist);
void SeqListInsertByVal(SeqList *plist, ElemType x);
void SeqListErasePos(SeqList *plist, int pos);
int SeqListFind(SeqList *plist, ElemType key);
void SeqListEraseVal(SeqList *plist, ElemType key);
void SeqListReverse(SeqList *plist);
///
bool IsFull(SeqList *plist)
{
//断言结构体不能为空,如果结构体为空,那么表也就不存在
assert(plist != NULL);
return plist->size >= plist->capacity;
}
bool IsEmpty(SeqList *plist)
{
assert(plist != NULL);
return plist->size == 0;
}
void SeqListInit(SeqList *plist)
{
plist->capacity = SEQLIST_DEFAULT_SIZE;
plist->base = (ElemType*)malloc(sizeof(ElemType)* plist->capacity);
plist->size = 0;
}
void SeqListDestroy(SeqList *plist)
{
assert(plist != NULL);
free(plist->base);
plist->base = NULL;
plist->capacity = plist->size = 0;
}
void SeqListPushBack(SeqList *plist, ElemType x)
{
assert(plist != NULL);
if (IsFull(plist))
{
printf("顺序表已满,%d不能尾部插入.\n", x);
return;
}
plist->base[plist->size++] = x;
}
void SeqListPushFront(SeqList *plist, ElemType x)
{
assert(plist != NULL);
//判满
if (IsEmpty(plist))
{
printf("顺序表已满,%d不能头部插入.\n", x);
return;
}
//头插
for (int i = plist->size; i > 0; i--)
{
plist->base[i] = plist->base[i - 1];
}
plist->base[0] = x;
plist->size++;
}
void SeqListShow(SeqList *plist)
{
assert(plist != NULL);
for (size_t i = 0; i < plist->size; i++)
{
printf("%d ", plist->base[i]);
}
printf("\n");
}
size_t SeqListLength(SeqList *plist)
{
assert(plist != NULL);
return plist->size;
}
void SeqListPopBack(SeqList *plist)
{
assert(plist != NULL);
//判空
if (IsEmpty(plist))
{
printf("顺序表已空,不能进行尾部删除.\n");
return;
}
//只要减少元素个数我们就认为删除掉了
plist->size--;
}
void SeqListClear(SeqList *plist)
{
assert(plist != NULL);
plist->size = 0;
}
bool SeqListInsertByPos(SeqList *plist, int pos, ElemType x)
{
assert(plist != NULL);
if (IsFull(plist))
{
printf("顺序表溢满,%d不能在%d位置插入.\n", x, pos);
return false;
}
if (pos<0 || pos>plist->size)
{
printf("要插入的位置%d是非法位置,%d不能插入.\n", pos, x);
return false;
}
for (size_t i = plist->size; i > pos; i--)
{
plist->base[i] = plist->base[i - 1];
}
plist->base[pos] = x;
plist->size++;
return true;
}
void SeqListSort(SeqList *plist)
{
assert(plist != NULL);
for (size_t i = 0; i < plist->size - 1; i++)
{
for (size_t j = 0; j < plist->size - i - 1; j++)
{
if (plist->base[j] > plist->base[j+1])
{
Swap(&plist->base[j], &plist->base[j + 1]);
}
}
}
}
size_t SeqListCapacity(SeqList *plist)
{
assert(plist != NULL);
return plist->capacity;
}
void SeqListPopFront(SeqList *plist)
{
assert(plist != NULL);
//判空
if (IsEmpty(plist))
{
printf("顺序表已空,不能进行头部删除.\n");
return;
}
for (size_t i = 0; i < plist->size; i++)
{
plist->base[i] = plist->base[i + 1];
}
plist->size--;
}
void SeqListInsertByVal(SeqList *plist, ElemType x)
{
assert(plist != NULL);
if (IsFull(plist))
{
printf("顺序表已满,%d不能被插入.\n", x);
return;
}
#if 0
size_t pos = 0;
//查找插入的位置
while (pos < plist->size && x > plist->base[pos])
{
pos++;
}
for (size_t i = plist->size; i > pos; i--)
{
plist->base[i] = plist->base[i - 1];
}
plist->base[pos] = x;
plist->size++;
#endif
size_t end = plist->size - 1;
while (end >= 0 && x<plist->base[end])
{
plist->base[end + 1] = plist->base[end];
end--;
}
plist->base[end+1] = x;
plist->size++;
}
void SeqListErasePos(SeqList *plist, int pos)
{
assert(plist != NULL);
if (IsFull(plist))
{
printf("顺序表已满,不能在%d位置删除数据.\n", pos);
return;
}
//判断位置是否合法
if (pos < 0 && pos >= plist->size)
{
printf("删除的位置非法,不能删除数据.\n");
return;
}
for (size_t i = pos; i < plist->size; i++)
{
plist->base[i] = plist->base[i + 1];
}
plist->size--;
}
int SeqListFind(SeqList *plist, ElemType key)
{
assert(plist != NULL);
int pos = 0;
while (pos<plist->size && key != plist->base[pos])
{
pos++;
}
if (pos == plist->size)
{
pos = -1;
}
return pos;
}
void SeqListEraseVal(SeqList *plist, ElemType key)
{
assert(plist != NULL);
int pos = SeqListFind(plist, key);
if (pos == -1)
{
return;
}
SeqListErasePos(plist, pos);
}
void SeqListReverse(SeqList *plist)
{
assert(plist != NULL);
if (plist->size == 1)
return;
int start = 0, end = plist->size - 1;
while (start < end)
{
Swap(&plist->base[start], &plist->base[end]);
start++;
end--;
}
}
#endif /*_SQLIST_H_*/
ソースファイルDatabase.cpp
#include "seqlist.h"
int main()
{
SeqList list;
SeqListInit(&list);
ElemType item;
int pos;
int select = 1;
bool flag;
while (select)
{
printf("*************************************\n");
printf("*[1] push_back [2] push_front *\n");
printf("*[3] show_list [0] quit_system *\n");
printf("*[4] pop_back [5] pop_front *\n");
printf("*[6] insert_pos [7] insert_val *\n");
printf("*[8] erase_pos [9] erase_val *\n");
printf("*[10] find [11] length *\n");
printf("*[12] capacity [13] sort *\n");
printf("*[14] reverse [15] clear *\n");
printf("*[16] front [17] back *\n");
printf("*[18] binary_find [19] erase_all *\n");
printf("*************************************\n");
printf("请选择:>");
scanf("%d", &select);
if (select == 0)
{
break;
}
switch (select)
{
case 1:
printf("请输入要插入的数据<以-1结束>:");
while (scanf("%d", &item), item != -1)
{
SeqListPushBack(&list, item);
}
printf("头部插入数据成功...\n");
break;
case 2:
printf("请输入要插入的数据<以-1结束>:");
while (scanf("%d", &item), item != -1)
{
SeqListPushFront(&list, item);
}
printf("尾部插入数据成功...\n");
break;
case 3:
SeqListShow(&list);
break;
case 4:
SeqListPopBack(&list);
printf("尾部删除数据成功...\n");
break;
case 5:
SeqListPopFront(&list);
printf("头部删除数据成功...\n");
break;
case 6:
printf("请输入要插入的位置:>");
scanf("%d", &pos);
printf("请输入要插入的元素:>");
scanf("%d", &item);
flag = SeqListInsertByPos(&list, pos, item);
if (flag)
{
printf("插入数据成功...\n");
}
else
{
printf("插入数据失败...\n");
}
break;
case 7:
printf("请输入要插入的元素:>");
scanf("%d", &item);
SeqListSort(&list);
SeqListInsertByVal(&list, item);
printf("按值插入成功...\n");
break;
case 8:
printf("请输入要删除的位置:>");
scanf("%d", &pos);
SeqListErasePos(&list, pos);
printf("删除数据成功...\n");
break;
case 9:
printf("请输入要删除的元素:>");
scanf("%d", &item);
SeqListEraseVal(&list, item);
break;
case 10:
printf("请输入要查找的关键值:>");
scanf("%d", &item);
pos = SeqListFind(&list, item);
if (pos == -1)
{
printf("数据查找失败.\n");
}
else
{
printf("数据查找成功.\n");
}
break;
case 11:
printf("SeqList Length = %d\n", SeqListLength(&list));
break;
case 12:
printf("SeqList Capacity = %d\n", SeqListCapacity(&list));
break;
case 13:
SeqListSort(&list);
printf("排序成功...\n");
break;
case 14:
SeqListReverse(&list);
printf("转制完成...\n");
break;
case 15:
SeqListClear(&list);
break;
default:
printf("命令出错,请重新输入......\n");
break;
}
system("pause");
system("cls");//clear sreen
}
SeqListDestroy(&list);
return 0;
}