C語言實現(xiàn)順序表的基本操作指南(注釋很詳細)
更新時間:2021年10月12日 14:24:47 作者:__ericZhao
線性表是最簡單的數(shù)據(jù)結(jié)構(gòu),而順序表又是最簡單的線性表,其基本思想是用一段地址連續(xù)的儲存單元依次存儲線性表的數(shù)據(jù)元素,下面這篇文章主要給大家介紹了關(guān)于C語言實現(xiàn)順序表的基本操作,需要的朋友可以參考下
創(chuàng)建一個結(jié)構(gòu)體用于存放順序表相關(guān)數(shù)據(jù)
#define SEQTYPE int typedef struct SeqList { SEQTYPE* data; int size; //有效數(shù)據(jù)個數(shù) int capacity; //容量 }SeqList;
初始化順序表
void SeqListInit(SeqList* pq) { CheckNull(pq); pq->data = NULL; pq->capacity = 0; pq->size = 0; }
插入元素
- 插入到表頭;
- 插入到指定位置;
- 插入到尾部;
先檢查容量是否夠用
void CheckCapacity(SeqList* pq) { CheckNull(pq); //如果空間滿了,擴容 if (pq->size >= pq->capacity) { int newcapacity = pq->capacity == 0 ? 4 : pq->capacity * 2; SEQTYPE* new = (SEQTYPE*)realloc(pq->data, sizeof(SEQTYPE) * newcapacity); if (new == NULL) { perror("realloc"); exit(-1); } pq->data = new; pq->capacity = newcapacity; } puts("增容成功"); } //往順序表指定位置插入數(shù)據(jù) void SeqListInsert(SeqList* pq, int pos) { CheckNull(pq); assert(pos <= pq->size); SEQTYPE InsertVal; if (pos == -1) { printf("請分別輸入添加的數(shù)據(jù)和位置,空格隔開:>"); scanf("%d %d", &InsertVal, &pos); if (pos > pq->size) { printf("請正確輸入\n"); return; } } else { printf("請輸入添加的數(shù)據(jù):>"); scanf("%d", &InsertVal); } //檢查容量是否足夠 CheckCapacity(pq); //插入數(shù)據(jù) int end = pq->size; int begin = pos; while (begin < end) { pq->data[end] = pq->data[end - 1]; --end; } pq->data[pos] = InsertVal; ++pq->size; printf("添加成功\n"); } //往順序表末位置插入數(shù)據(jù) void SeqListPushBack(SeqList* pq) { CheckNull(pq); SeqListInsert(pq, pq->size); } //往順序表首位置插入數(shù)據(jù) void SeqListPushFront(SeqList* pq) { CheckNull(pq); SeqListInsert(pq, 0); }
刪除元素
- 刪除首元素;
- 刪除指定位置元素;
- 刪除尾部元素;
//從順序表指定位置刪除數(shù)據(jù) void SeqListErase(SeqList* pq, int pos) { CheckNull(pq); if (pos == -1) { printf("請輸入要刪除數(shù)據(jù)的位置:>"); scanf("%d", &pos); if (pos < 0 || pos >= pq->size) { printf("請正確輸入\n"); return; } } int begin = pos; int end = pq->size - 1; while (begin < end) { pq->data[begin] = pq->data[begin + 1]; ++begin; } --pq->size; puts("刪除成功"); } //從順序表末位置刪除數(shù)據(jù) void SeqListPophBack(SeqList* pq) { CheckNull(pq); SeqListErase(pq, pq->size - 1); } //從順序表首位置刪除數(shù)據(jù) void SeqListPophFront(SeqList* pq) { CheckNull(pq); SeqListErase(pq, 0); }
元素修改
- 找到目標元素;
- 直接修改該元素的值;
//修改順序表指定位置數(shù)據(jù) void SeqListModify(SeqList* pq) { CheckNull(pq); int pos; SEQTYPE x; printf("請輸入修改的位置和新的數(shù)據(jù),空格隔開:>"); scanf("%d %d", &pos, &x); if (pos < 0 && pos >= pq->size) { printf("請正確輸入\n"); return; } pq->data[pos] = x; puts("修改成功"); }
查找元素
查找目標元素,算法多種,比如二分,插值等等,這里使用順序查找算法,具體代碼如下:
//查找所需數(shù)據(jù)是否存在順序表中 void SeqListFindData(SeqList* pq) { CheckNull(pq); SEQTYPE x; printf("請輸入要查找的數(shù)據(jù):>"); scanf("%d", &x); for (int i = 0; i < pq->size; i++) { if (pq->data[i] == x) { printf("所需查詢數(shù)據(jù)存在,下標為:>%d\n", i); return; } } printf("找不到\n"); }
排序元素
//排序順序表 void SeqListSort(SeqList* pq) { CheckNull(pq); int option = 0; printf("輸入0為升序,1為降序:>"); scanf("%d", &option); for (int i = 0; i < pq->size - 1; i++) { for (int j = 0; j < pq->size - i - 1; j++) { if (pq->data[j] > pq->data[j + 1]) { SEQTYPE tmp = pq->data[j]; pq->data[j] = pq->data[j + 1]; pq->data[j + 1] = tmp; } } } if (option) { SeqListReverse(pq); return; } }
元素反轉(zhuǎn)
//順序表反轉(zhuǎn) void SeqListReverse(SeqList* pq) { CheckNull(pq); int left = 0; int right = pq->size - 1; while (left < right) { SEQTYPE tmp = pq->data[left]; pq->data[left] = pq->data[right]; pq->data[right] = tmp; ++left; --right; } }
源碼
- 以上是順序表常用的功能操作,下面附上完整代碼,VS2019環(huán)境
SeqList.c
#include "SeqList.h" void CheckNull(SeqList* pq) { if (pq == NULL) { perror("pq::"); exit(-1); } } //初始化順序表 void SeqListInit(SeqList* pq) { CheckNull(pq); pq->data = NULL; pq->capacity = 0; pq->size = 0; } void SeqListDestory(SeqList* pq) { CheckNull(pq); free(pq->data); pq->data = NULL; pq->size = 0; pq->capacity = 0; } void CheckCapacity(SeqList* pq) { CheckNull(pq); //如果空間滿了,擴容 if (pq->size >= pq->capacity) { int newcapacity = pq->capacity == 0 ? 4 : pq->capacity * 2; SEQTYPE* new = (SEQTYPE*)realloc(pq->data, sizeof(SEQTYPE) * newcapacity); if (new == NULL) { perror("realloc"); exit(-1); } pq->data = new; pq->capacity = newcapacity; } puts("增容成功"); } void SeqListPrint(SeqList* pq) { CheckNull(pq); if (pq->size == 0) printf("\n"); else { for (int i = 0; i < pq->size; i++) { printf("%d ", pq->data[i]); } puts("\n--------------------------------------"); } } //往順序表末位置插入數(shù)據(jù) void SeqListPushBack(SeqList* pq) { CheckNull(pq); SeqListInsert(pq, pq->size); } //往順序表首位置插入數(shù)據(jù) void SeqListPushFront(SeqList* pq) { CheckNull(pq); SeqListInsert(pq, 0); } //往順序表指定位置插入數(shù)據(jù) void SeqListInsert(SeqList* pq, int pos) { CheckNull(pq); assert(pos <= pq->size); SEQTYPE InsertVal; if (pos == -1) { printf("請分別輸入添加的數(shù)據(jù)和位置,空格隔開:>"); scanf("%d %d", &InsertVal, &pos); if (pos > pq->size) { printf("請正確輸入\n"); return; } } else { printf("請輸入添加的數(shù)據(jù):>"); scanf("%d", &InsertVal); } //檢查容量是否足夠 CheckCapacity(pq); //插入數(shù)據(jù) int end = pq->size; int begin = pos; while (begin < end) { pq->data[end] = pq->data[end - 1]; --end; } pq->data[pos] = InsertVal; ++pq->size; printf("添加成功\n"); } //從順序表指定位置刪除數(shù)據(jù) void SeqListErase(SeqList* pq, int pos) { CheckNull(pq); if (pos == -1) { printf("請輸入要刪除數(shù)據(jù)的位置:>"); scanf("%d", &pos); if (pos < 0 || pos >= pq->size) { printf("請正確輸入\n"); return; } } int begin = pos; int end = pq->size - 1; while (begin < end) { pq->data[begin] = pq->data[begin + 1]; ++begin; } --pq->size; puts("刪除成功"); } //從順序表末位置刪除數(shù)據(jù) void SeqListPophBack(SeqList* pq) { CheckNull(pq); SeqListErase(pq, pq->size - 1); } //從順序表首位置刪除數(shù)據(jù) void SeqListPophFront(SeqList* pq) { CheckNull(pq); SeqListErase(pq, 0); } //修改順序表指定位置數(shù)據(jù) void SeqListModify(SeqList* pq) { CheckNull(pq); int pos; SEQTYPE x; printf("請輸入修改的位置和新的數(shù)據(jù),空格隔開:>"); scanf("%d %d", &pos, &x); if (pos < 0 && pos >= pq->size) { printf("請正確輸入\n"); return; } pq->data[pos] = x; puts("修改成功"); } //查找順序表指定位置數(shù)據(jù) void SeqListFindPos(SeqList* pq) { CheckNull(pq); int pos; printf("請輸入要查找數(shù)據(jù)的位置:>"); scanf("%d", &pos); if (pos < 0 && pos >= pq->size) { printf("請正確輸入\n"); return; } for (int i = 0; i < pq->size; i++) { if (pq->data[i] == pq->data[pos]) { printf("查找位置的數(shù)據(jù)為:>%d\n", pq->data[pos]); break; } } } //查找所需數(shù)據(jù)是否存在順序表中 void SeqListFindData(SeqList* pq) { CheckNull(pq); SEQTYPE x; printf("請輸入要查找的數(shù)據(jù):>"); scanf("%d", &x); for (int i = 0; i < pq->size; i++) { if (pq->data[i] == x) { printf("所需查詢數(shù)據(jù)存在,下標為:>%d\n", i); return; } } printf("找不到\n"); } //排序順序表 void SeqListSort(SeqList* pq) { CheckNull(pq); int option = 0; printf("輸入0為升序,1為降序:>"); scanf("%d", &option); for (int i = 0; i < pq->size - 1; i++) { for (int j = 0; j < pq->size - i - 1; j++) { if (pq->data[j] > pq->data[j + 1]) { SEQTYPE tmp = pq->data[j]; pq->data[j] = pq->data[j + 1]; pq->data[j + 1] = tmp; } } } if (option) { SeqListReverse(pq); return; } } //順序表反轉(zhuǎn) void SeqListReverse(SeqList* pq) { CheckNull(pq); int left = 0; int right = pq->size - 1; while (left < right) { SEQTYPE tmp = pq->data[left]; pq->data[left] = pq->data[right]; pq->data[right] = tmp; ++left; --right; } }
test.c
#include "SeqList.h" void menu() { printf("######################################################\n"); printf("##### 1. Print 2. Insert #####\n"); printf("##### 3. PushFront 4. PushBack #####\n"); printf("##### 5. PopFront 6. PopBack #####\n"); printf("##### 7. FindPos 8. FindData #####\n"); printf("##### 9. Modify 10. Erase #####\n"); printf("##### 11. EMPTY 12. Sort #####\n"); printf("##### 13. Reverse 0. Exit #####\n"); printf("######################################################\n"); } enum Option { EXIT, PRINT, INSERT, PUSHFRONT, PUSHBACK, POPFRONT, POPBACK, FINDPOS, FINDDATA, MODIFY, ERASE, EMPTY, SORT, REVERSE, }; int main() { int option = 0; int posi = -1; SeqList s; SeqListInit(&s); do { menu(); printf("請選擇:>"); scanf("%d", &option); switch (option) { case PRINT: SeqListPrint(&s); break; case INSERT: SeqListInsert(&s, posi); break; case PUSHFRONT: SeqListPushFront(&s); break; case PUSHBACK: SeqListPushBack(&s); break; case POPFRONT: SeqListPophFront(&s); break; case POPBACK: SeqListPophBack(&s); break; case FINDPOS: SeqListFindPos(&s); break; case FINDDATA: SeqListFindData(&s); break; case MODIFY: SeqListModify(&s); break; case ERASE: SeqListErase(&s, posi); break; case EMPTY: SeqListDestory(&s); break; case SORT: SeqListSort(&s); break; case REVERSE: SeqListReverse(&s); break; case EXIT: SeqListDestory(&s); printf("退出\n"); break; default: printf("請正確輸入\n"); break; } } while (option); return 0; }
SeqList.h
#pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <errno.h> #include <string.h> // #define SEQTYPE int typedef struct SeqList { SEQTYPE* data; int size; //有效數(shù)據(jù)個數(shù) int capacity; //容量 }SeqList; //初始化順序表 void SeqListInit(SeqList* pq); //銷毀順序表 void SeqListDestory(SeqList* pq); //打印順序表 void SeqListPrint(SeqList* pq); //往順序表指定位置插入數(shù)據(jù) void SeqListInsert(SeqList* pq, int pos); //往順序表末位置插入數(shù)據(jù) void SeqListPushBack(SeqList* pq); //往順序表首位置插入數(shù)據(jù) void SeqListPushFront(SeqList* pq); //從順序表指定位置刪除數(shù)據(jù) void SeqListErase(SeqList* pq, int pos); //從順序表末位置刪除數(shù)據(jù) void SeqListPophBack(SeqList* pq); //從順序表首位置刪除數(shù)據(jù) void SeqListPophFront(SeqList* pq); //修改順序表指定位置數(shù)據(jù) void SeqListModify(SeqList* pq); //查找順序表指定位置數(shù)據(jù) void SeqListFindPos(SeqList* pq); //查找所需數(shù)據(jù)是否存在順序表中 void SeqListFindData(SeqList* pq); //排序順序表 void SeqListSort(SeqList* pq); //順序表反轉(zhuǎn) void SeqListReverse(SeqList* pq);
總結(jié)
到此這篇關(guān)于C語言實現(xiàn)順序表的基本操作指南的文章就介紹到這了,更多相關(guān)C語言實現(xiàn)順序表基本操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Protocol Buffer技術(shù)深入理解(C++實例)
C++實例Protocol Buffer技術(shù)詳解,感興趣的朋友可以了解下2013-01-01C++指針和數(shù)組:字符和字符串、字符數(shù)組的關(guān)聯(lián)和區(qū)別
字符串是一種重要的數(shù)據(jù)類型,但是c語言并沒有顯示的字符串數(shù)據(jù)類型,因為字符串以字符串常量的形式出現(xiàn)或者存儲于字符數(shù)組中。在C++標準模板庫(STL)中提供了string類,實現(xiàn)了對字符串的封裝。2022-12-12C++封裝遠程注入類CreateRemoteThreadEx實例
這篇文章主要介紹了C++封裝遠程注入類CreateRemoteThreadEx實例,詳細講述了注入DLL到指定的地址空間以及從指定的地址空間卸載DLL的方法,需要的朋友可以參考下2014-10-10