2018.11.25学习记录

1.选择排序:从未排序中选择出最小的放到已排序的末尾。

代码:(转自http://www.cnblogs.com/0201zcr/p/4764427.html

/**
     * 选择排序算法
     * 在未排序序列中找到最小元素,存放到排序序列的起始位置  
     * 再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。 
     * 以此类推,直到所有元素均排序完毕。 
     * @param numbers
     */
    public static void selectSort(int[] numbers)
    {
    int size = numbers.length; //数组长度
    int temp = 0 ; //中间变量
    
    for(int i = 0 ; i < size ; i++)
    {
        int k = i;   //待确定的位置
        //选择出应该在第i个位置的数
        for(int j = size -1 ; j > i ; j--)
        {
        if(numbers[j] < numbers[k])
        {
            k = j;
        }
        }
        //交换两个数
        temp = numbers[i];
        numbers[i] = numbers[k];
        numbers[k] = temp;
    }
    }

2.稀疏矩阵的压缩存储

转自:http://www.cnblogs.com/Lynn-Zhang/p/5413364.html

没有经过处理的稀疏矩阵其实就是一个特殊的二维数组,数组中的大部分元素是0或者其他类型的非法值,只有少数几个非零元素。

为了实现压缩存储,可以只存储稀疏矩阵的非0元素。在存储稀疏矩阵中的非0元素时,必须要存储该元素的行列号以及元素值。

一般用三元组法或者十字链表法:

(1)三元组表示稀疏矩阵可大大节省空间,但是当涉及到矩阵运算时,要大量移动元素。

(2)十字链表表示法可以避免大量移动元素。

我们可以封装一个三元组类来存储这些元素。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

//三元组

template<class T>

struct Triple

{

    size_t _row;   //行

    size_t _col;   //列

    T _value;      //值

      

    Triple<T>::Triple()    //定义无参的构造函数

    {}

    Triple(size_t row, size_t col,T value)

        :_row(row)

        , _col(col)

        , _value(value)

    {}

};

创建稀疏矩阵。利用容器,可以非常方便的存储这些元素,相当于用一个动态数组来存储。要求按照行优先的顺序存储,方便打印稀疏矩阵时,按照行列顺序依次打印非0元素。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

template<class T>   //利用容器实现稀疏矩阵的压缩存储

SparseMatrix<T>::SparseMatrix(const T* array, size_t  row, size_t  col, const T& invalid)  //初始化

    :_rowMatrix(row)

    , _colMatrix(col)

    ,_invalid(invalid)

{

    for (size_t i = 0; i < _rowMatrix; ++i)

    {

        for (size_t j = 0; j < _colMatrix; ++j)

        {

            if (array[i*col + j] != invalid)

            {

                Triple<T> cur(i, j, array[i*col + j]);

                _array.push_back(cur);

            }

        }

    }

}

列序转置法:以矩阵的列序进行转置,这样经过转置后得到的三元组容器序列正好是以行优先存储的。时间复杂度为 O(_colMatrix*_array.size())

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

template<class T>    //列序转置

SparseMatrix<T> SparseMatrix<T>::Transport()

{

    assert(_array.size()!=0);

    SparseMatrix<T> ret;

    ret._rowMatrix = _colMatrix;

    ret._colMatrix = _rowMatrix;

    ret._invalid = _invalid;

    ret._array.reserve(this->_array.size());

      

    for (size_t j = 0; j < _colMatrix; j++)

    {

        size_t index = 0;

        while (index < _array.size())

        {

            if (_array[index]._col == j)

            {

                Triple<T> tp(_array[index]._col, _array[index]._row, _array[index]._value);

                ret._array.push_back(tp); 

            }

            index++;

        }

        if (this->_array.size() == ret._array.size())

        {

            break;

        }

    }

    return ret;

}

  

快速转置法:事先确定矩阵每一列第一个元素在容器中的位置,在对稀疏矩阵转置时,通过对原容器的遍历,依次直接将元素放在新容器的恰当位置。时间复杂度为O(_colMatrix+_array.size())

转置前,要先确定原矩阵每一列非零元素的个数,然后求出每一列非零元素在新容器中的正确位置。

设置两个整型数组RowCounts[_colMatrix]、RowStart[_colMatrix]分别用来存放三元组容器中每一列非零元素的个数以及每一列第一个非零元素在新容器中的正确位置。

RowStart[0] = 0;     RowStart[col] = RowStart[col - 1] + RowCounts[col - 1];

列号 0 1 2 3 4
RowCounts[col] 2 0 2 0 2
RowStart[col] 0 2 2 4 4

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

template<class T>

SparseMatrix<T> SparseMatrix<T>::FastTranaport() //快速转置

{

    assert(_array.size() != 0);

    size_t index = 0;

    SparseMatrix<T> ret;

    ret._rowMatrix = _colMatrix;

    ret._colMatrix = _rowMatrix;

    ret._invalid = _invalid;

    ret._array.resize(_array.size());

    int *RowCounts = new int[_colMatrix];

    int *RowStart = new int[_colMatrix];

    memset(RowCounts, 0, _colMatrix*sizeof(int));

    memset(RowStart, 0, _colMatrix*sizeof(int));

    for (size_t i = 0; i < _array.size(); i++)

    {

        RowCounts[_array[i]._col]++;

    }

    RowStart[0] = 0;

    for (size_t i = 1; i < _colMatrix; i++)

    {

        RowStart[i] = RowStart[i - 1] + RowCounts[i - 1];

    }

    Triple<T> tp;

    for (size_t i = 0; i < _array.size(); i++)

    {

        tp._row = _array[i]._col;

        tp._col = _array[i]._row;

        tp._value = _array[i]._value;

        ret._array[RowStart[_array[i]._col]++] = tp;

    }

    delete [] RowCounts;

    delete [] RowStart;

    return ret;

}

3.三对角矩阵的压缩存储、

(转自:https://www.cnblogs.com/6wenhong6/p/9833107.html

a1,1   a1,2          

a2,1  a2,2  a2,3      0

  a3,2  a3,3  a3,4

    ...    ...     ...

 0      an-1,n-2  an-1,n-1 an-1,n

        an,n-1    an,n

三对角矩阵指n阶方阵的非零元素ai,j聚集在主对角线及其两边的两条线上,即|i-j|≤1,其余位置均为0,如果使用二维数组进行存储,则会浪费大量空间,对此可以使用一维数组将其压缩存储。

其中元素总数为:2+3*(n-2)+2=3n-2,则可以定义一个一维数组B[3n-2],则ai,j在B中的位置为k(注意k从0开始)

则在ai,j之前的元素个数为

第1行:2

第2行:3

第3行:3

...

第i-1行:3

第i行:j-i+1

则k=2+3*(i-2)+j-i+1=2i+j-3

若已知k,则ai,j为

i=(k+1)/3+1,(k+1:向右偏移一个单位;3:每行3个元素;+1:i从1开始)

j=k-2i+3(由k的计算公式可得)

4.数据结构中的线性结构------线性表、栈和队列,非线性结构------树和图。

线性表:

线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。

线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。

5.有一个数组a[5]

(1)&a和a做右值----数值相同意义不同

&a是数组的首地址

a是数组首元素的地址

(2)a和&a[0]做右值----数值和意义完全相同

6.数组的插入要考虑越界问题

猜你喜欢

转载自blog.csdn.net/qq_37910848/article/details/84499425
今日推荐