线性表的顺序存储结构称为顺序表。
说明: 1.顺序表是用一段地址连续的存储单元依次存储线性表的数据元素。 2.通常用一维数组来实现顺序表,C++中数组的下标从0开始。 3.线性表中第i个元素存储在数组(C++)中下标为i-1的位置。 |
顺序表的实现
将线性表的抽象数据类型定义在顺序表存储结构下用C++的类实现
const int MaxSize = 100; template <class T> class SeqList { private: T data[MaxSize];//存放数据的数组 int length; //线性表长度 public: SeqList();//无参构造函数 SeqList(T a[], int n);//有参构造函数 ~SeqList(){} int Length();//求线性表的长度 int Get(int i);//按位查找,取线性表的第i个元素 int Locate(T x);//按值查找,求线性表中值为x的元素 int Insert(int i, T x);//在线性表中的第i个位置插入值为x的元素 int Delete(int i);//删除线性表中的第i个元素 void PrintList();//遍历线性表,按序号回复输出各元素 }; |
构造函数
template <class T> SeqList<T>::SeqList(T a[], int n) { if (n > MaxSize) throw "参数非法"; for (int i = 0; i < n; i ++) data[i] = a[i]; length = n; } |
按位查找
template <class T> int SeqList<T>::Get(int i) { if (i < 1 || i > length) throw "查找位置非法"; else cout << "第" << i << "个元素是" << data[i-1] << endl; return 0; } |
按值查找
template <class T> int SeqList<T>::Locate(T x) { for (int i = 0; i < length; i ++) if (x == data[i]) cout << x << "是第" << i+1 << "个元素" << endl; return 0; } |
插入
template <class T> int SeqList<T>::Insert(int i, T x) { if (length >=MaxSize) throw "上溢"; if (i < 1 || i > length+1) throw "位置异常"; for (int j = length; j > i-1; j --) data[j] = data[j-1]; data[i-1] = x; length ++; return 0; } |
删除
template <class T> int SeqList<T>::Delete(int i) { if (0 == length) throw "下溢"; if (i < 1 || i > length) throw "位置异常"; int x = data[i-1];//暂存第i个元素 for (int j = i-1; j < length; j ++) data[j] = data[j+1]; length --; cout << "删除第" << i << "个元素" << x << endl; return 0; } |
思考:已知数组A[n]中的元素为整型,设计算法将其调整为左右两部分,左边所有元素为奇数,右边所有元素为偶数;
我想了想首先想出了这个算法:
定义一个数组b[n];从左边开始存储a[n]中的奇数,从右边开始存储a[n]中的偶数,
int a[10] = {1,2,3,4,5,6,7,8,9,10};//定义数组a int b[10]; //定义一个数组b用来存储a int j = 0; int k = sizeof(a)/4 - 1;
for (int i = 0; i < 10; i ++) { if (a[i]%2 == 1) { b[j] = a[i];//奇数放到数组b左边 j ++; } else if (a[i]%2 == 0) { b[k] = a[i]; //偶数放到数组b右边 k --; } else if (i == k) break; } for (i = 0; i < 10; i ++) cout << b[i] << " "; cout << endl; |
思考:以顺序表为存储结构,写一实现线性表就地逆置的算法。
int a[10] = {1,2,3,4,5,6,7,8,9,10}; int k = sizeof(a)/4 - 1; for (int i = 0; i < k+1; i ++) { int tmp = a[i]; a[i] = a[k-i]; a[k-i] = tmp; if (5 == i) break; } for (i = 0; i < k+1; i ++) cout << a[i] << " "; cout << endl; |
思考:约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,m为任意一个正整数。从第一个人开始顺时针方向自1起顺序报数,报到m时停止并且报m的人出列,再从他的下一个人开始重新从1报数,报到m时停止并且报m的人出列。如此下去,直到所有人全部出列为止。要求设计一个程序模拟此过程,对任意给定的m和n,求出出列编号序列
int n, m; cout << "输入n:"; cin >> n; cout << "输入m:"; cin >> m; int *a = new int [n];
for (int i = 0; i < n; i ++) a[i] = 0; //将数组全部初始化为0; int j = 1;//计数器; int x = 0;//已经出去的个数 while (1) { for (i = 0; i < n; i ++) { if (a[i] == 0 && j++%m == 0) //仔细考虑为什么要用j++%m == 0,如果换成其他可以吗? { cout << j << " "; a[i] = 1; x ++; cout << "第" << i+1 << "个出列" << endl; j = 1; } } if (x == n) break; //用来跳出while循环 } |