存儲結構
順序存儲結構:邏輯上連續,物理存儲上也連續
鏈式存儲結構:邏輯上連續,物理存儲上不連續
順序表–操作數據
順序表是在計算機內存中以數組的形式保存的線性表。
順序存儲:
類似於數組,順序表比數組多帶一個元素來記錄存儲的元素個數count
定長順序表
定長順序表 —》類似於數組
不定長順序表—》C++的STL vector
數組適用於值比較固定的情況 存儲數據
數組沒有成套的方法
計數法:(即順序表的定義)
struct data
{
int num[10];
int count;
}
程序案例----
Seqlist.h
#pragma once
//定義順序表 以數組形式存儲 所以無法擴容 寫判滿函數
#ifndef _SEQLIST_H
#define _SEQLIST_H
#define LENGTH 10
typedef int ElemType;
typedef struct _Seqlist
{
ElemType data[LENGTH];//存儲數據元素的空間 固定大小的
int count;//記錄存儲的數據元素個數
}Seqlist,*pSeqlist;//*pSeqlist是指針
static bool IsFull(pSeqlist seq);//判滿
static bool IsEmpty(pSeqlist seq);//判空
bool InitList_Sq(pSeqlist seq);//初始化
void InsertList_SqOfHead(pSeqlist seq, ElemType val);//插入元素 頭插 以及插入的元素
void InsertList_SqOfTail(pSeqlist seq, ElemType val);//插入元素 尾插 以及插入的元素
void InsertList_SqOfPos(pSeqlist seq, ElemType val,int pos);//插入元素 指定位置插入
void ShowList_Sq(pSeqlist seq);
void DeleteList_SqOfHead(pSeqlist seq);//頭刪
void DeleteList_SqOfTail(pSeqlist seq);//尾刪
void DeleteList_SqOfPos(pSeqlist seq,int pos);//指定位置刪除
bool FindList_SqOfPos(pSeqlist seq, int pos, ElemType &val);//根據位置返回元素的值
int FindList_SqOfVal(pSeqlist seq, ElemType val);//根據元素的值返回位置
int FindList_SqOfLocate(pSeqlist seq, ElemType val,
bool(*compare)(ElemType,ElemType));//根據函數條件compare和val值查找元素---函數指針
void ReverseList_Sq(pSeqlist seq, void(*Swap)(ElemType&, ElemType&));//逆置順序表元素
//還是傳入了函數指針 因爲萬一交換的是結構體裏的某一個怎麼辦
bool compare(ElemType a, ElemType b);
void Swap(ElemType &a, ElemType &b);
#endif
/*
typedef int ElemType;
#define LENGTH 10
typedef struct _Alterlist
{
ElemType *data;//存儲數據元素的空間首地址得指針
int count;//記錄已存儲的數據元素個數
int listsize;//記錄存儲空間元素總大小
}Alterlist, *pAlterlist;//*pAlterlist是指針
bool InitList_Sq(pAlterlist alist)
{
assert(alist != NULL);//斷言指針是否爲空 只在debug版本下有效
if (alist == NULL)
{
return false;//保證release版本也能判斷
}
alist->data = (ElemType *)malloc(sizeof(ElemType)*LENGTH);
}
*/
Seqlist.cpp
// Seqlist.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include "pch.h"
#include"assert.h"
#include"Seqlist.h"
#include<string.h>
#include <iostream>
using namespace std;
// 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單
// 調試程序: F5 或調試 >“開始調試”菜單
// 入門提示:
// 1. 使用解決方案資源管理器窗口添加/管理文件
// 2. 使用團隊資源管理器窗口連接到源代碼管理
// 3. 使用輸出窗口查看生成輸出和其他消息
// 4. 使用錯誤列表窗口查看錯誤
// 5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目
// 6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”並選擇 .sln 文件
//判斷是否滿 寫成靜態函數是因爲靜態函數將函數符號生成爲LOCAL 只能在本文件中訪問 外部不能訪問
static bool IsFull(pSeqlist seq)
{
if (seq->count == LENGTH)
{
return true;
}
return false;
}
static bool IsEmpty(pSeqlist seq)//判空
{
if (seq->count == 0)
{
return true;
}
return false;
}
bool compare(ElemType a , ElemType b)
{
if ( a == b)
{
return true;
}
return false;
}
void Swap(ElemType &a, ElemType &b)
{
ElemType c = a;
a = b;
b = c;
}
bool InitList_Sq(pSeqlist seq)
{
assert(seq != NULL);//斷言指針是否爲空 只在debug版本下有效
if (seq == NULL)
{
return false;//保證release版本也能判斷
}
seq->count = 0;
seq->data[30];
}
void InsertList_SqOfHead(pSeqlist seq, ElemType val)
{
if (IsFull(seq))
{
cout << "內存已滿!" << endl;
return;
}
//移動已有的數據
for (int i = seq->count; i > 0; i--)
{
seq->data[i] = seq->data[i - 1];
}
seq->data[0] = val;
seq->count++;
}
void InsertList_SqOfTail(pSeqlist seq, ElemType val)
{
if (IsFull(seq))
{
cout << "內存已滿!" << endl;
return;
}
seq->data[seq->count++] = val;//直接在尾部進行插入數據
}
void InsertList_SqOfPos(pSeqlist seq, ElemType val, int pos)
{
if (IsFull(seq))
{
cout << "內存已滿!" << endl;
return;
}
//判斷pos位置是否合法
if (pos<0 || pos>seq->count)//pos=count相當於尾插 因爲是數組
{
return;
}
if (pos > seq->count)
pos = seq->count;
//在pos位置插入和頭插一個思想 同樣是移動數據 只不過是在pos位置後進行移動
for (int i = seq->count; i > pos; i--)
{
seq->data[i] = seq->data[i - 1];
}
seq->data[pos] = val;
seq->count++;
}
void ShowList_Sq(pSeqlist seq)
{
for (int i = 0; i < seq->count; ++i)
{
printf("%d", seq->data[i]);
}
printf("\n");
}
void DeleteList_SqOfHead(pSeqlist seq)
{
if (IsEmpty(seq))
{
return;
}
for (int i = 0; i <seq->count-1; i++)
{
seq->data[i] = seq->data[i + 1];
}
seq->count--;
}
void DeleteList_SqOfTail(pSeqlist seq)
{
if (IsEmpty(seq))
{
return;
}
seq->count--;
}
void DeleteList_SqOfPos(pSeqlist seq, int pos)
{
if (IsEmpty(seq))
{
return;
}
if (pos<0 || pos>=seq->count)//pos=count相當於要刪除一個不存值的 因爲是數組
{
return;
}
if (pos > seq->count)
pos = seq->count;
for (int i = pos; i < seq->count-1; i++)
{
seq->data[i] = seq->data[i + 1];
}
seq->count--;
}
bool FindList_SqOfPos(pSeqlist seq, int pos, ElemType &val)
{
if (pos < 0 || pos >= seq->count)//pos=count相當於要刪除一個不存值的 因爲是數組
{
return false;
}
val = seq->data[pos];
return true;
}
int FindList_SqOfVal(pSeqlist seq, ElemType val)
{
for (int i = 0; i < seq->count; i++)
{
if (seq->data[i] == val)
{
return i;
}
}
return -1;
}
//如果ElemType val是個結構體 用上面方法就不行了 不能進行直接比較 就得用下面這個
int FindList_SqOfLocate(pSeqlist seq, ElemType val, bool(*compare)(ElemType, ElemType))
{
for (int i = 0; i < seq->count; ++i)
{
if (compare(val, seq->data[i]))//使用我傳的函數來進行判斷
{
return i;
}
}
return false;
}
void ReverseList_Sq(pSeqlist seq,void(*Swap)(ElemType&,ElemType&))//逆置
{
int i = 0;
int j = seq->count - 1;
for (; i < j; ++i, --j)
{
swap(seq->data[i], seq->data[j]);
}
}
main.cpp
#include "pch.h"
#include"Seqlist.h"
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int main()
{
/*-------------------------- -定長順序表-----------------------------------------------------*/
/* Seqlist seq;//棧區定義的順序表 是由系統管理的 程序員只管堆區的數據(malloc)
InitList_Sq(&seq);
InsertList_SqOfHead(&seq, 10);
InsertList_SqOfHead(&seq, 20);
InsertList_SqOfHead(&seq, 30);
ShowList_Sq(&seq);//302010
InsertList_SqOfTail(&seq, 40);
ShowList_Sq(&seq);//30201040
InsertList_SqOfPos(&seq, 40,2);//3020401040
ShowList_Sq(&seq);
DeleteList_SqOfHead(&seq);//20401040
ShowList_Sq(&seq);
DeleteList_SqOfTail(&seq);//204010
ShowList_Sq(&seq);
int val = 0;
FindList_SqOfPos(&seq, 1, val);
cout << val << endl;
int i = FindList_SqOfVal(&seq, 10);
cout << "i: " << i << endl;
int j = FindList_SqOfLocate(&seq, 40, compare);
cout <<"j: "<< j << endl;
ReverseList_Sq(&seq, Swap);//逆置
ShowList_Sq(&seq);
*/
}
不定長順序表
不定長順序表與定長順序表基本相似,都是在計算機內存中以數組的形式保存的線性表,邏輯相鄰,地址也相鄰,可以通過下標任意訪問。區別是不定長順序表可擴容(動態開闢)。
結構如何構造:
數據存放在數組中,需要一個變量記錄有效個數(即存放了數據的個數),需要擴容那麼就要知道當前內存是否爲滿,設置一個變量記錄總長度。所以結構體設計爲下圖:
main.cpp
#include "pch.h"
#include"Alterlist.h"
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int main()
{
_AlterList seq;//棧區定義的順序表 是由系統管理的 程序員只管堆區的數據(malloc)
InitList_AL(&seq);
Insert_ALHead(&seq, 10);
Insert_ALHead(&seq, 20);
Insert_ALHead(&seq, 30);
ShowALList_Sq(&seq);//302010
Delete_AL(&seq);//20401040
Insert_ALHead(&seq, 40);
Insert_ALHead(&seq, 50);
Insert_ALHead(&seq, 60);
Insert_ALHead(&seq, 70);
Insert_ALHead(&seq, 80);
ShowALList_Sq(&seq);
}
AlterList.cpp
#include "pch.h"
#include "AlterList.h"
#include <assert.h>
#include <string.h>
#include <malloc.h>
#include<iostream>
using namespace std;
//*********************************
// 判空函數
bool IsEmpty(pAlterList alist)
{
if (alist->count == 0)
return true;
return false;
}
// 判滿函數
bool IsFull(pAlterList alist)
{
if (alist->count == alist->listsize)
return true;
return false;
}
//*********************************
bool InitList_AL(pAlterList alist)
{
assert(alist != NULL);//assert只在DEBUG版本有效,若編譯成release版本則被忽略
if (alist == NULL)
{
return false;
}
alist->data = (ElemType *)malloc(sizeof(ElemType) * LENGTH);
assert(alist->data != NULL);
if (alist->data == NULL)
{
return false;
}
alist->count = 0;
alist->listsize = LENGTH;
return true;
}
// 擴容函數
void resize1(pAlterList alist)//用realloc進行擴容
{
alist->data = (ElemType *)realloc(alist->data, sizeof(ElemType)*(alist->listsize + LENGTH));
assert(alist->data != NULL);//如果這個內存可以擴容
alist->listsize += LENGTH;//更新當前順序表的長度
}
void resize2(pAlterList alist)//申請一個更大空間,將舊數據拷貝,釋放舊空間
{
ElemType *tmp = (ElemType *)malloc(sizeof(ElemType)*(alist->listsize + LENGTH));
for (int i = 0; i < alist->count; ++i)
{
tmp[i] = alist->data[i];
}
delete[]alist->data;//刪掉原先指針指向的內存
alist->data = tmp;//將原先指針指向新開闢的內存
alist->listsize += LENGTH;
}
void Insert_ALHead(pAlterList alist, ElemType val)
{
if (IsFull(alist))
{
cout << "內存已滿!" << endl;
return;
}
//移動已有的數據
for (int i = alist->count; i > 0; i--)
{
alist->data[i] = alist->data[i - 1];
}
alist->data[0] = val;
alist->count++;
}
void Delete_AL(pAlterList alist)
{
if (IsEmpty(alist))
{
return;
}
for (int i = 0; i < alist->count - 1; i++)
{
alist->data[i] = alist->data[i + 1];
}
alist->count--;
}
void ShowALList_Sq(pAlterList alist)
{
for (int i = 0; i < alist->count; ++i)
{
printf("%d", alist->data[i]);
}
printf("\n");
}
AlterList.h
#pragma once
#pragma once
typedef int ElemType;
#define LENGTH 6
typedef struct _AlterList
{
ElemType *data; // 指向存儲數據元素的空間首地址的指針
int count; // 記錄已存儲的數據元素的個數
int listsize; // 記錄存儲空間元素總大小
}AlterList, *pAlterList;
//初始化函數
bool InitList_AL(pAlterList alist);
//判空
bool IsEmpty(pAlterList alist);
//判滿
bool IsFull(pAlterList alist);
//擴容1
void resize1(pAlterList alist);
//擴容2
void resize2(pAlterList alist);
// 插入元素的函數
void Insert_ALHead(pAlterList alist,ElemType val);
// 刪除函數
void Delete_AL(pAlterList alist);
// 查找
//void Select_AL(pAlterList alist, ElemType val);
// 元素逆置
//void Insert_AL(pAlterList alist, ElemType val);
// 清空元素
// 銷燬順序表
// 顯示元素
void ShowALList_Sq(pAlterList alist);