因为最近在拿严蔚敏版的《数据结构》复习相关知识,所以就通过动手实现来加深理解,在这里与大家分享。话不多说,直接上代码,注释比较详细,就不另外解说了。
首先是List_Sq.h,这里使用了类模板以及函数模板,便于将该顺序线性表使用在不同的基本数据类型。
#ifndef __List_Sq_H__ #define __List_Sq_H__ #include<iostream> #include<cstdlib> using namespace std; const int LIST_INIT_SIZE = 100; //线性表的初始空间分配量 const int LIST_INCREMENT = 10; // 线性表存储空间的分配增量 const int OVER_FLOW = -2; // 内存分配失败状态代码 // 动态分配顺序存储结构的线性表 template <class T> struct SqList{ T *elem; // 存储空间基址 int length; // 当前长度 int listsize; // 当前分配的存储容量 }; template <class T> class List_Sq { public: void InitList_Sq(SqList<T> &L); // 构造一个空的线性表L void DestroyList_Sq(SqList<T> &L); // 销毁线性表L bool ClearList_Sq(SqList<T> &L); // 将L重置为空表 bool ListEmpty_Sq(SqList<T> L); // 若L为空表,返回true,否则返回false int ListLength_Sq(SqList<T> L); // 返回L中数据元素的个数 bool GetElem_Sq(SqList<T> L, int i, T &e); // 用e返回L中第i个数据元素的值 int LocateElem_Sq(SqList<T> L, T e, bool(*compare)(T e1, T e2)); // 返回L中第1个与e满足关系compare()的数据元素的位序。 // 若这样的数据元素不存在,则返回值为0 bool PriorElem_Sq(SqList<T> L, T cur_e, T &pre_e); // 若cur_e是L中的数据元素,且不是第一个,则用pre_e返回它的前驱 // 否则操作失败,pre_e无定义 bool NextElem_Sq(SqList<T> L, T cur_e, T &next_e); // 若cur_e是L中的数据元素,且不是最后一个,则用pre_e返回它的后继 // 否则操作失败,pre_e无定义 bool ListInsert_Sq(SqList<T> &L, int i, T e); // 在L中第i个位置之前插入新的数据元素e,L的长度加1 bool ListDelete_Sq(SqList<T> &L, int i, T &e); // 删除L的第i个数据元素,并用e返回其值,L的长度减1 void output(SqList<T> L); // 输出线性表中的所有元素 }; template <class T> void List_Sq<T>::InitList_Sq(SqList<T> &L) { L.elem = (T *)malloc(LIST_INIT_SIZE * sizeof(T)); if (!L.elem) exit(OVER_FLOW); // 存储分配失败 L.length = 0; // 空表长度为0 L.listsize = LIST_INIT_SIZE; // 初始存储容量 } template <class T> void List_Sq<T>::DestroyList_Sq(SqList<T> &L) { if (L.elem != NULL) free(L.elem); // 释放存储空间 } template <class T> bool List_Sq<T>::ClearList_Sq(SqList<T> &L) { if (L.elem == NULL) // 线性表不存在 return false; else { free(L.elem); // 释放并重新分配存储空间 L.elem = (T *)malloc(LIST_INIT_SIZE * sizeof(T)); L.length = 0; return true; } } template <class T> bool List_Sq<T>::ListEmpty_Sq(SqList<T> L) { if (0 == L.length) return true; else return false; } template <class T> int List_Sq<T>::ListLength_Sq(SqList<T> L) { return L.length; } template <class T> bool List_Sq<T>::GetElem_Sq(SqList<T> L, int i, T &e) { if (i < 1 || i > L.length) // i不在合法范围内 return false; else { e = L.elem[i - 1]; return true; } } template <class T> int List_Sq<T>::LocateElem_Sq(SqList<T> L, T e, bool(*compare)(T e1, T e2)) { // 在顺序线性表L中查找第一个值与e满足compare()的元素的位序 // 若找到,则返回其在L中的位序,否则返回0 int i = 1; // i的初值为第一个元素的位序 T *p = L.elem; // p的初值为第一个元素的存储位置 while (i <= L.length && !(*compare)(*p++, e)) ++i; if (i <= L.length) return i; else return 0; } template <class T> bool List_Sq<T>::PriorElem_Sq(SqList<T> L, T cur_e, T &pre_e) { T *p = L.elem, *q = L.elem + L.length - 1; // p初值为第一个元素的存储位置,q为最后一个元素的存储位置 for (p; p <= q; ++p){ if (*p == cur_e && p != L.elem) { // cur_e是线性表中的数据元素且不是第一个 pre_e = *(--p); return true; } } return false; } template <class T> bool List_Sq<T>::NextElem_Sq(SqList<T> L, T cur_e, T &next_e) { T *p = L.elem, *q = L.elem + L.length - 1; for (p; p < q; ++p){ // cur_e是线性表中的数据元素且不是最后一个 if (*p == cur_e) { next_e = *(++p); return true; } } return false; } template <class T> bool List_Sq<T>::ListInsert_Sq(SqList<T> &L, int i, T e) { if (i < 1 || i > L.length + 1) // i值不合法 return false; if (L.length >= L.listsize) { // 当期存储空间已满,增加分配 T *newbase = (T *)realloc(L.elem, (L.listsize + LIST_INCREMENT) * sizeof(T)); if (!newbase) exit(OVER_FLOW); // 存储分配失败 L.elem = newbase; // 新基址 L.listsize += LIST_INCREMENT; // 增加存储容量 } T *q = &(L.elem[i - 1]); // q为插入位置 for (T *p = &(L.elem[L.length - 1]); p >= q; --p) *(p + 1) = *p; // 插入位置及之后的元素右移 *q = e; // 插入e ++L.length; // 表长增1 return true; } template <class T> bool List_Sq<T>::ListDelete_Sq(SqList<T> &L, int i, T &e) { if (i < 1 || i > L.length) // i值不合法 return false; T *p = &(L.elem[i - 1]); // p为被删除元素的位置 e = *p; // 被删除元素的值赋给e T *q = L.elem + L.length - 1; // 表尾元素的位置 for (++p; p <= q; ++p) *(p - 1) = *p; // 被删除元素之后的元素左移 --L.length; // 表长减1 return true; } template <class T> void List_Sq<T>::output(SqList<T> L) { T *p = L.elem, *q = L.elem + L.length - 1; for (p; p <= q; ++p) cout << *p << " "; cout << endl; } template <class T> bool compare(T e1, T e2) { // 比较函数,这里以相等为例 if (e1 == e2) return true; else return false; } template <class T> void MergeList_Sq(SqList<T> La, SqList<T> Lb, SqList<T> &Lc) { // 已知顺序线性表La和Lb的元素按值非递减排列 // 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列 T *pa = La.elem, *pb = Lb.elem; Lc.listsize = Lc.length = La.length + Lb.length; T *pc = Lc.elem = (T *)malloc(Lc.listsize * sizeof(T)); if (!Lc.elem) exit(OVER_FLOW); // 存储分配失败 T *pa_last = La.elem + La.length - 1; T *pb_last = Lb.elem + Lb.length - 1; while (pa <= pa_last && pb <= pb_last) { // 归并 if (*pa <= *pb) *pc++ = *pa++; else *pc++ = *pb++; } while (pa <= pa_last) // 插入La的剩余元素 *pc++ = *pa++; while (pb <= pb_last) // 插入Lb的剩余元素 *pc++ = *pb++; } #endif // !__List_Sq__H
接下来是测试代码main.cpp。
#include "List_Sq.h" int main() { char ch; SqList<char> L, M, U; List_Sq<char> list_sq, list_merge, list_union; list_sq.InitList_Sq(L); // 初始化线性表 list_sq.ListInsert_Sq(L, 1, 'a'); // 插入五个字符并输出 list_sq.ListInsert_Sq(L, 2, 'b'); list_sq.ListInsert_Sq(L, 3, 'c'); list_sq.ListInsert_Sq(L, 4, 'd'); list_sq.ListInsert_Sq(L, 5, 'd'); list_sq.ListInsert_Sq(L, 6, 'e'); cout << "线性表中的初始元素为:"; list_sq.output(L); if (!list_sq.ListEmpty_Sq(L)) { cout << "线性表长:" << list_sq.ListLength_Sq(L) << endl; } list_sq.GetElem_Sq(L, 3, ch); cout << "第3个元素为:" << ch << endl; cout << "线性表中第一个与‘d’相等的元素的位序:" << list_sq.LocateElem_Sq(L, 'd', compare<char>) << endl; list_sq.PriorElem_Sq(L, 'b', ch); cout << "数据元素‘b’的前驱:" << ch << endl; list_sq.NextElem_Sq(L, 'b', ch); cout << "数据元素‘b’的后继:" << ch << endl; list_sq.ListDelete_Sq(L, 6, ch); cout << "删除第6个元素,该元素为:" << ch << endl; cout << "删除元素后的线性表为:"; list_sq.output(L); list_merge.InitList_Sq(M); list_merge.ListInsert_Sq(M, 1, 'a'); list_merge.ListInsert_Sq(M, 2, 'b'); list_merge.ListInsert_Sq(M, 3, 'f'); cout << "新建一个线性表:"; list_merge.output(M); MergeList_Sq(L, M, U); cout << "两个顺序线性表按值非递减排列合并后为:"; list_union.output(U); list_union.ClearList_Sq(U); cout << "将合并后的顺序线性表置空后为:"; list_union.output(U); cout << "销毁3个线性表,程序结束。" << endl; list_sq.DestroyList_Sq(L); list_merge.DestroyList_Sq(M); list_union.DestroyList_Sq(U); return 0; }
测试效果截图:
因个人水平有限,如有错误,还请各位批评指正。
顺序存储线性表的C++实现——严蔚敏版《数据结构》
猜你喜欢
转载自blog.csdn.net/hfutdog/article/details/77161539
今日推荐
周排行