顺序存储线性表的C++实现——严蔚敏版《数据结构》

      因为最近在拿严蔚敏版的《数据结构》复习相关知识,所以就通过动手实现来加深理解,在这里与大家分享。话不多说,直接上代码,注释比较详细,就不另外解说了。

     首先是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;
}


      测试效果截图:


     

    因个人水平有限,如有错误,还请各位批评指正。


猜你喜欢

转载自blog.csdn.net/hfutdog/article/details/77161539