您的位置:首页 > 理论基础 > 数据结构算法

数据结构笔记(C++描述)

2017-11-29 23:54 453 查看
1. 创建一个二维数组:

template<class T>
void make2dArray(T** &x, int numberOfRows, int numberOfColumns)
{
x= new T*[numberOfRows];
for( int i=0; i < numberOfRows; i++)
{
x[i] = new int[numberOfColumns];
}
}


2. 改变一维数组大小

template<class T>
void changeLength1D(T*& a, int oldLength, int newLength)
{
if (newLength < 0)
throw invalid_argument("new length must be >= 0");

T* temp = new T[newLength];              // new array
int number = min(oldLength, newLength);  // number to copy
copy(a, a + number, temp);
delete [] a;                             // deallocate old memory
a = temp;
}


3.改变二维数组大小

template <class T>
void changeLength2D(T** &a, int oldRow, int oldColumn, int newRow, int newColumn)
{
if (newRow < 0 || newColumn < 0)
{
throw invalid_argument("new row and column must be >=0");
}
T** temp = new T*[newRow];
for (int i = 0; i < newRow; i++)
{
temp[i] = new T[newColumn];
}
int co_number = min(oldColumn, newColumn);
int row_number = min(oldRow, oldColumn);
for (int i = 0; i < row_number; i++)
{
copy(a[i], a[i] + co_number, temp[i]);
}
for (int i = 0; i < oldRow; i++)
{
delete[] a[i];
}
delete[] a;
a = temp;
}


4.使用递归函数生成排列

template <class	T>
void permutations(T list[], int k, int m)
{
if (k == m)		//到达递归基础,输出排列(list[k:m]仅有一个排列输出)
{
copy(list, list + m + 1, ostream_iterator<T>(cout, ""));
cout << endl;
}
else//list[k:m]有多于一个排列,递归生成这些排列
{
for (int i = k; i <= m; i++)
{
swap(list[k], list[i]);		//交换位置以修改前缀
permutations(list, k + 1, m);
swap(list[k], list[i]);		//换回原位
}
}
}


5.矩阵转置(原地)

template<class T>
void transpose(T** a, int rows )
{
for(int i=0;i<rows;i++)
{
for(int j=i+1;j<rows;j++)
{
swap(a[i][j],a[j][i]);
}
}
}

6.矩阵乘法([m*n]*[n*p]矩阵)

template<class T>
void matrixMutiply(T **a, T **b, T **c, int m, int n, int p)
{
for (int i = 0; i < n; i++)		//固定行
{
for (int j = 0; j < p; j++) //固定列
{
T sum = 0;
for (int k = 0; k < n; k++)
{
sum += a[i][k] * b[k][j];
}
c[i][j] = sum;
}
}
return;
}

7.删除指定范围内的所有元素(线性表)

template<class T>
void arrayList<T>::removeRange(int start, int end)
{
if (start <0 || end >listSize)
{
throw illegalIndex;
}
if (start > end)
{
return;
}
copy(element + end, element + listSize, element + start);
int newSize = listSize - end + start;
for (int i = newSize; i < listSize; i++)
{
element[i].~T();
}
listSize = newSize;
return;
}

8.数组中隔一个元素删除一个元素

template<class T>
void arrayListWithHalf<T>::half()
{// Remove all odd indexed elements.

// move even indexed elements to new spots
for (int i = 2; i < listSize; i += 2)
element[i/2] = element[i];

// destroy uneeded elements
int newSize = (listSize + 1) / 2;
for (int i = newSize; i < listSize; i++)
element[i].~T();

listSize = newSize;
}

9. 合并两个升序线性表

template<class T>
void vectorListWithMerge<T>::merge(const vectorListWithMerge<T>& a,
const vectorListWithMerge<T>& b)
{// Make this the result of merging the sorted lists a and b.
vector<T>::iterator ia = a.element->begin();  // iterator for a
vector<T>::iterator aEnd = a.element->end();
vector<T>::iterator ib = b.element->begin();  // iterator for b
vector<T>::iterator bEnd = b.element->end();

element = new vector<T>;

// merge from a and b
while ((ia < aEnd) && (ib < bEnd))
if (*ia <= *ib)
{
element->push_back(*ia);
ia++;
}
else
{
element->push_back(*ib);
ib++;
}

// take care of left overs
element->insert(element->end(), ia, aEnd);
element->insert(element->end(), ib, bEnd);
}

10.箱子排序

//链表箱子排序
//将学生的分数按升序排序
//时间复杂度为O(range + n)
template<class T>
void chain<T>::binSort(int range)
{
//创建并初始化箱子
chainNode<T> **buttom,**top;
bottom = new chainNode<T>* [range + 1];
top = new chainNode<T>* [range + 1];
for(int b=0;b<=range;b++)
{
bottom[b] = Null;
}

//把链表节点分配给箱子
for(;firstNode != Null;firstNode = firstNode->next)
{
//把首节点加到箱子中
int theBin = firstNode->element; // 原函数重载了int()转换
if(buttom[theBin] == NULL)
{
//箱子为空
bottom[theBin] = top[theBin] = firstNode;
}
else
{
//箱子不空
top[theBin]->next = firstNode;
top[theBin] = firstNode;
}
}
//把箱子中节点收集到有序链表
chainNode<T> *y = NULL;
for(int theBin=0; theBin<= range;theBin++)
{
//箱子不空
if(buttom[theBin] != NULL)
{
if(y == NULL)
{
firstNode = buttom[theBin];
}
else
{
y->next = bottom[theBin];
}
y=top[theBin];
}
}
if(y->next != NULL)
{
y->next = NULL;
}
delete[] buttom;
delete[] top;
return;
}


11.基数排序(扩展箱子排序)

基数排序(radix sort)可以在O(N) 时间内,就可以对 0~n^c-1 之间的n个整数进行排序,其中c为整数常量.(箱子排序为O(n+range) =O(n^c))

例:假定对0-999之间的10个整数进行排序.

基数排序方法:

一. 利用箱子排序方法,根据最低位数字(即个位数字),对10个数字进行排序.

二.利用箱子排序方法对(一)的结果按次低位数字(十位数字)进行排序.(箱子排序是稳定排序,不会打乱次低位数字相同的节点之间的相对次序)

三.利用箱子排序方法对(二)的结果进行第三位数字的排序.

上述排序方法是以10为基数,把数分解为十进制数字进行排序.(单个箱子排序实际上等价于r=1000的基数排序)

12.并查集

(一)

//使用数组实现并查集算法

int *equivClass,n;
void initialize(int numberOfElement)
{//用每个类的一个元素,初始化numberOfElements个类
n = numberOfElements;
equivClass = new int[n + 1];
for(int e=1;e<=n;e++)
{
equivClass[e] =e;
}
}

void unite(int classA,int classB)
{ //合并类classA、classB
//假设类classA != classB
for(int k=1;k<=n;k++)
{
if(equivClass[k] == classB)
{
equivClass[k] = classA;
}
}
}

int find(int theElement)
{
return equivClass[theElement];
}
(二)

//链表实现并查集

struct equivNode
{
int equivClass,size,next;
}

equivNode *node;
int n;
void initailize(int numberOfElements)
{//用每个类的一个元素,初始化numberOfElements
n = numberOfElements;
node = new equivNode[n + 1];
for(int e=1; e<=n; e++)
{
node[e].equivClass = e;
node[e].next = 0; //链表中没有下个节点
node[e].size = 1;
}
}

void unite(int classA,int classB)
{ //合并classA,classB
//假设classA != classB
//classA classB是链表首元素

//使classA成为较小的类
if(node[classA].size > node[classB])
{
swap(classA,classB);
}

//改变较小类的equivClass值
int k;
for(k=classA;node[k].next !=0; k=node[k].next)
{
node[k].equivClass = classB;
}
node[k].equivClass = classB; //链表最后一个节点

//在链表classB的首元素后插入链表classA
//修改新链表大小
node[classB].size +=node[classA].size;
node[k].next = node[classB].next;
node[classB].next = classA;
}

int find(int theElement)
{
return node[theElement].equivClass;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: