順序表簡介:
順序表是簡單的一種線性結構,他們可以說是連續存儲元素的,也可以稱之爲數組。順序表可以快速定位到第幾個元素的位置,中間不允許有空值。插入、刪除時需要移動大量的元素!
順序表的三個要素:
- 用elems記錄存儲位置的基地址;
- 分配一段連續的存儲空間size;
- 用length記錄實際的元素個數,即順序表的長度。
順序表的結構體定義
#define MAX_SIZE 100
struct SEQUENCE {
int *elems; // 存儲整型的順序表的基地址
int length; // 順序表的長度
int size; // 順序表的總空間大小
}
順序表的定義與初始化
#define MAX_SIZE 100
// 定義
struct SEQUENCE {
int* memory; // 首地址
int length; // 大小/元素個數
int size; // 內存大小
};
// 初始化
bool initSEQUENCE(struct SEQUENCE& L) {
L.memory = new int[MAX_SIZE]; // 分配內存
if (!L.memory) { // 判斷是否分配失敗
return false;
}
L.length = 0; // 空表長度爲0
L.size = MAX_SIZE; // 順序表的總空間大小
return true;
}
如下圖:
初始化只是給順序表分配內存大小!
尾部插入數據
// 尾部插入數據
bool insertSEQUENCE(struct SEQUENCE& L, int e) { // 參數一:順序表的引用; 參數二:需要插入的元素
if (L.length == L.size) return false; // 合法性檢查,如果順序表已滿,則無法插入
L.memory[L.length] = e; // 將元素插入下標爲length的位置
L.length++; // 順序表的長度加1
return true;
}
如下圖:
在尾部插入元素,只需要將該元素賦值給length下標,並將length++即可。
中間插入數據
// 中間插入數據
bool insert(struct SEQUENCE& L, int i, int e) { // 參數一:順序表的引用;參數二:插入位置(下標);參數三:插入元素
if (i < 0 || i >= L.length) return false; // 合法性檢查,中間插入元素,插入位置i不可能大於等當前元素的長度length
if (L.length == L.size) return false; // 合法性檢查,如果順序表已滿,則無法插入
for (int j = L.length - 1; j >= i; j--) { // 把元素都往後移動一個位置,直到遇到插入位置爲止
L.memory[j+1] = L.memory[j];
}
L.memory[i] = e; // 賦值需要插入的元素到下標i的位置
L.length++; // 順序表的長度加1
return true;
}
如下圖:
中間插入一個元素,需要將插入位置的後面所有元素都往後移動一個位置,然後再插入。
元素刪除
// 元素刪除
bool deleteSEQUENCE(struct SEQUENCE& L, int i) { // 參數一:順序表的引用;參數二:刪除位置(下標)
if (i < 0 || i >= L.length) return false; // 合法性檢查,刪除的元素,位置(下標)i不可能大於等當前元素的長度length
if (i == L.length - 1) { // 刪除最後一個元素
L.length--; // 只需要將length長度減一即可
return true;
}
for (int j = i; j < L.length - 1; j++) { // 刪除中間某個元素
L.memory[j] = L.memory[j + 1]; // 刪除位置的後續元素往前移
}
L.length--; // length長度減一
return true;
}
如下圖:
刪除某個元素,只需將其後面所有的元素都往前移動一個位置,將其覆蓋掉,最後將length減一即可。
順序表銷燬
當程序要結束時,也是需要將順序表的內存釋放掉,應爲他的內存是從堆上分配的!
// 釋放順序表中分配的內存
void Delete(struct SEQUENCE& L) { // 參數一:順序表的引用
if (L.memory) { // 判斷指針是否有內存,有,則釋放;無,則跳過
delete[] L.memory;
L.length = 0; // 記得也要講長度設爲0
}
}
如下圖:
打印順序表的結果
根據項目的實際情況定奪。
// 打印輸出結果
void print(struct SEQUENCE& L) {
cout << "順序表的長度爲:" << L.length << ", 內存大小爲:" << L.size << endl;
for (int i = 0; i < L.length; i++) {
cout << L.memory[i] << ", ";
}
cout << endl;
}
測試代碼:
#include <iostream>
#include <Windows.h>
using namespace std;
#define MAX_SIZE 100
struct SEQUENCE {
int* memory; // 首地址
int length; // 大小/元素個數
int size; // 內存大小
};
// 初始化
bool initSEQUENCE(struct SEQUENCE& L) {
L.memory = new int[MAX_SIZE]; // 分配內存
if (!L.memory) { // 判斷是否分配失敗
return false;
}
L.length = 0; // 空表長度爲0
L.size = MAX_SIZE; // 順序表的總空間大小
return true;
}
// 尾部插入數據
bool insertSEQUENCE(struct SEQUENCE& L, int e) { // 參數一:順序表的引用; 參數二:需要插入的元素
if (L.length == L.size) return false; // 合法性檢查,如果順序表已滿,則無法插入
L.memory[L.length] = e; // 將元素插入下標爲length的位置
L.length++; // 順序表的長度加1
return true;
}
// 中間插入數據
bool insert(struct SEQUENCE& L, int i, int e) { // 參數一:順序表的引用;參數二:插入位置(下標);參數三:插入元素
if (i < 0 || i >= L.length) return false; // 合法性檢查,中間插入元素,插入位置i不可能大於等當前元素的長度length
if (L.length == L.size) return false; // 合法性檢查,如果順序表已滿,則無法插入
for (int j = L.length - 1; j >= i; j--) { // 把元素都往後移動一個位置,直到遇到插入位置爲止
L.memory[j+1] = L.memory[j];
}
L.memory[i] = e; // 賦值需要插入的元素到下標i的位置
L.length++; // 順序表的長度加1
return true;
}
// 元素刪除
bool deleteSEQUENCE(struct SEQUENCE& L, int i) { // 參數一:順序表的引用;參數二:刪除位置(下標)
if (i < 0 || i >= L.length) return false; // 合法性檢查,刪除的元素,位置(下標)i不可能大於等當前元素的長度length
if (i == L.length - 1) { // 刪除最後一個元素
L.length--; // 只需要將length長度減一即可
return true;
}
for (int j = i; j < L.length - 1; j++) { // 刪除中間某個元素
L.memory[j] = L.memory[j + 1]; // 刪除位置的後續元素往前移
}
L.length--; // length長度減一
return true;
}
// 釋放順序表中分配的內存
void Delete(struct SEQUENCE& L) { // 參數一:順序表的引用
if (L.memory) { // 判斷指針是否有內存,有,則釋放;無,則跳過
delete[] L.memory;
L.length = 0; // 記得也要講長度設爲0
}
}
// 打印輸出結果
void print(struct SEQUENCE& L) {
cout << "順序表的長度爲:" << L.length << ", 內存大小爲:" << L.size << endl;
for (int i = 0; i < L.length; i++) {
cout << L.memory[i] << ", ";
}
cout << endl;
}
int main(void) {
struct SEQUENCE sequence;
// 初始化
cout << "正在初始化順序表。。。" << endl;
if (initSEQUENCE(sequence)) {
cout << "順序表初始化成功!" << endl;
} else {
cout << "順序表初始化失敗!" << endl;
return -1;
}
// 尾部插入元素
for (int i = 0; i < 5; i++) {
if (insertSEQUENCE(sequence, i)) {
cout << "插入成功!" << endl;
} else {
cout << "插入失敗!" << endl;
}
}
print(sequence);
// 中間插入元素
if (insert(sequence, 4, 10)) {
cout << "插入成功!" << endl;
} else {
cout << "插入失敗!" << endl;
}
print(sequence);
// 刪除元素
if (deleteSEQUENCE(sequence, 5)) {
cout << "刪除成功!" << endl;
} else {
cout << "刪除失敗!" << endl;
}
print(sequence);
// 銷燬順序表
Delete(sequence);
print(sequence);
system("pause");
return 0;
}
運行截圖:
順序表項目實戰
使用順序表實現浪漫星空,且星星慢慢移動退出屏幕。
效果:
下面是實現代碼:
star.h頭文件
#pragma once
#ifndef _STAR_H_
#define _STAR_H_
#define WINDOWS_X 840
#define WINDOWS_Y 600
#define STAR_SCORE 100 // 星星個數
#define RADII 3 // 隨機半徑
#define COLOUR 6 // 顏色系數
enum STATE {
PAUSE, //
UP, // 上
DOWN, // 下
LEFT, // 左
RIGHT, // 右
CONST, // 個數
};
struct STAR {
int starX;
int starY;
int radii; // 半徑
int colour; // 顏色
int step; // 顏色系數和跳躍間隔
STATE state; // 星星狀態
};
struct SEQUENCE {
struct STAR* memory; // 首地址
int length; // 大小/元素個數
int size; // 內存大小
};
// 順序表的接口
bool initSEQUENCE(struct SEQUENCE& L);
bool insertSEQUENCE(struct SEQUENCE& L, struct STAR e);
bool deleteSEQUENCE(struct SEQUENCE& L, int i);
void Delete(struct SEQUENCE& L);
void print(struct SEQUENCE& L);
#endif
實現結構體接口:starSEQUENCE.cpp
#include <iostream>
#include "star.h"
using namespace std;
// 初始化
bool initSEQUENCE(struct SEQUENCE& L) {
L.memory = new struct STAR[STAR_SCORE];
if (!L.memory) {
return false;
}
L.length = 0;
L.size = STAR_SCORE;
return true;
}
// 尾部插入數據
bool insertSEQUENCE(struct SEQUENCE& L, struct STAR e) {
if (L.length == L.size) return false;
L.memory[L.length] = e;
L.length++;
return true;
}
// 元素刪除
bool deleteSEQUENCE(struct SEQUENCE& L, int i) {
if (i < 0 || i >= L.length) return false;
if (i == L.length - 1) { // 刪除最後一個元素
L.length--;
return true;
}
for (int j = i; j < L.length - 1; j++) { // 刪除中間某個元素
L.memory[j] = L.memory[j + 1]; // 刪除位置的後續元素往前移
}
L.length--;
return true;
}
void Delete(struct SEQUENCE& L) {
if (L.memory) {
delete[] L.memory;
L.length = 0;
}
}
// 打印輸出結果
void print(struct SEQUENCE& L) {
cout << "順序表的長度爲:" << L.length << ", 內存大小爲:" << L.size << endl;
for (int i = 0; i < L.length; i++) {
cout << "第" << i + 1 << "顆星星: x = " << L.memory[i].starX << ", y = " << L.memory[i].starY <<
"半徑 = " << L.memory[i].radii << endl;
}
cout << endl;
}
mian函數實現
#include <graphics.h>
#include <iostream>
#include <Windows.h>
#include <cstdlib>
#include <ctime>
#include "star.h"
using namespace std;
// 星星的初始化
void initStar(struct STAR &_star) {
int rgb = 0;
_star.state = UP;
_star.starX = rand() % WINDOWS_X; // 0 - 839
_star.starY = rand() % (WINDOWS_Y - 100); // 0 - 499
_star.radii = rand() % RADII + 1; // 0 - 3
_star.step = rand() % COLOUR + 1;
rgb = 255 * _star.step / COLOUR;
_star.colour = RGB(rgb, rgb, rgb);
}
// 星星移動
void moveStar(struct SEQUENCE &star, int i) {
if (star.memory[i].state == PAUSE) return;
setfillcolor(RGB(0, 0, 0)); // 將星星擦除掉
solidcircle(star.memory[i].starX, star.memory[i].starY, star.memory[i].radii);
if (star.memory[i].state == UP) {
star.memory[i].starY -= star.memory[i].step;
if (star.memory[i].starY < 0) deleteSEQUENCE(star, i); // 判斷如果星星超出範圍,便刪除
} else if (star.memory[i].state == DOWN) {
star.memory[i].starY += star.memory[i].step;
if (star.memory[i].starY > WINDOWS_Y) deleteSEQUENCE(star, i); // 判斷如果星星超出範圍,便刪除
} else if (star.memory[i].state == LEFT) {
star.memory[i].starX -= star.memory[i].step;
if (star.memory[i].starX < 0) deleteSEQUENCE(star, i); // 判斷如果星星超出範圍,便刪除
} else if (star.memory[i].state == RIGHT) {
star.memory[i].starX += star.memory[i].step;
if (star.memory[i].starX < WINDOWS_X) deleteSEQUENCE(star, i); // 判斷如果星星超出範圍,便刪除
}
setfillcolor(star.memory[i].colour); // 將星星畫上去
solidcircle(star.memory[i].starX, star.memory[i].starY, star.memory[i].radii);
}
int main(void) {
struct SEQUENCE star;
struct STAR _star;
// 初始化星星在順序標中保存
initSEQUENCE(star);
initgraph(WINDOWS_X, WINDOWS_Y);
srand((unsigned int)time(NULL));
// 星星的初始化
for (int i = 0; i < STAR_SCORE; i++) {
initStar(_star);
insertSEQUENCE(star, _star);
}
// 畫星星
for (int i = 0; i < star.length; i++) {
setfillcolor(star.memory[i].colour);
solidcircle(star.memory[i].starX, star.memory[i].starY, star.memory[i].radii);
}
//system("pause");
while (1) {
// 星星移動
for (int i = 0; i < star.length; i++) {
moveStar(star, i);
}
if (star.length == 0) {
break;
}
Sleep(50);
}
system("pause");
closegraph();
return 0;
}
順序表總結:
順序表可以說是一個數組,但是他比數組還要靈活。實現順序表是使用結構體,順序表的各種操作都是使用函數接口完成的。只需要設計好函數接口,順序表還是很有用的!