数据结构与算法学习笔记(第二章 线性表)

记一些第一次学习的时候不知道或者理解有偏差的东西吧

  • 记住下面这张表
    数据结构与算法学习笔记(第二章 线性表)_第1张图片
  • 关于顺序表元素存储位置的计算
    先举个例子:如果每个元素占用8个单元,ai的存储位置是2000单元,则ai+1的存储位置是:?
    答案:2008单元。(别理解错了,让你求的是存储位置不是下标!!!)
    抛砖引玉:所有数据元素的存储位置均可由第一个元素的存储位置得到(“由第i个元素的存储位置得到”这里推得的):
    LOC(ai)=LOC(a1)+(i-1)×L,L是占用的单元量。该运算时间复杂度是O(1)。这个公式体现了随机存取的概念(可以获得任何一个元素的存储位置(地址)!)LOC(a1)称为基地址。这也是顺序表的优点
  • 符号常量——#define宏定义的对象,const定义的对象都称为符号常量
    #define MAX_SIZE=100;数组定义可以包含符号常量但不可以有变量!
  • 关于顺序表中结构体定义的思考
    数据结构与算法学习笔记(第二章 线性表)_第2张图片
    这里有个结构体里定义了个存储空间的基地址。

数据结构与算法学习笔记(第二章 线性表)_第3张图片
这是对于该定义的解释。我们进行动态存储分配。先定义一个指针,指针可以作为数组基地址(此时还不是),然后你用new或者malloc分配动态存储空间然后赋给SqList.elem,这里elem指针就真正能作为数组基地址了,然后你可以找其他存储空间的地址了。这样看起来更灵活一些啦!

  • 关于ElemType(一般结构体里出现),这个东西在实现的时候改成你需要的数据类型即可,或者,你在函数,结构体外写一个如typedef char(或者int) ElemType;,也可以。
  • 类C语言可以参杂C++的一些语法,怎么方便怎么来。
  • 数组逻辑位序(0、1、2、3…)和物理位序(1、2、3、4…)差1,这个很关键,涉及到算法如何描述数组中的元素位置。
  • ASL公式的Pi,这么理解,因为随机查找,因此我想查找每一个元素的概率(几率)为Pi,然后再✖需要查找的次数(因算法而异),就能算出ASL(平均查找长度(平均时间复杂度))了。(ASL=ΣPiCi,其中Σ下是i=1,上是n)实际上ASL像概率论里的期望值E(X)。我们也会在计算其他算法中用到ASL的公式,来计算其他算法的平均时间复杂度了。
    顺序表(顺序查找)的ASL=(n+1)/2,即顺序查找的时间复杂度为O(n)
  • 写算法要多考虑异常处理,鲁棒性要好
  • 写顺序表插入算法的时候,以从最后一个元素到插入位置的原元素依次往后放的思想(删除相反,删除是从第i个删除元素到第n(线性表表长)-1个元素依次前移)来写,这样你计算时间复杂度根据ASL公式也好算!注意算法是在表述数组的逻辑位序还是物理位序!
  • 插入算法,插入位置是i,移动x次,插入前顺序表有n个元素,我们知道插在最后的空位(第n+1个元素)移动0次,插在最后元素(第n个元素)移动1次,依照这个规律推算下去,所以i+x=n+1,所以普遍情况(规律)是移动n-i+1次。
  • 顺序表插入、删除、查找算法平均时间复杂度为O(n)
  • 顺序表也有优点的,
    1.随机存取
    2.存储密度大(表中元素都挨着存着,存储密度=结点本身所占存储量/结点结构所占存储量,顺序表的存储密度为1,存储密度是最大的。

链表

  • 头指针用来记录链表第一个元素的地址,链表名可以取头指针名
  • 结点:数据元素的存储映像
  • 首元结点:链表中存储第一个数据元素a1的结点
  • 头结点:为了操作方便,在首元结点之前加了个该结点
  • 头指针为空,证明链表是空表
  • 头指针指向头结点,头结点为空,证明链表是空表
  • 关于单链表突然想到的一个问题
    我的问题:问一个非常奇怪的问题,为什么单链表的指针域指向的是下个结点而非下个结点的数据域,我想定义成数据域里的数据类型的指针可不可以呢,这样就能指向下一个数据域了。
    总结大家的解答:
    我搞懂了,如果按照我问题上所想的,
    想要增删结点,只能增删数据域,指针域删不掉,就等于该结点删不掉,那这样增删就毫无意义。所以,问题里我想的那种情况有缺陷,缺陷就是增删结点的问题。,我那么想违背发明链表的目的。

    数据结构与算法学习笔记(第二章 线性表)_第4张图片
  • 此种销毁单链表的思路非常好,清晰明了,值得学习!
  • 以下是代码实现销毁单链表L,请和图示搭配学习
Status DestroyList_L(LinkList &L)
{
	Lnode *p;
	while(L)
	{
		p=L;
		L=L->next;
		delete p;
	}
	return OK;
}
  • 哦,还有创表是LinkList p,创结点是Lnode p,创结点指针是Lnode *p,这么些都很直观,方便阅读。
  • 单链表的算法相关我做成了一个脑图,欢迎查阅
    单链表
  • 双向链表和循环链表我没记,原理基于单链表,可以推理,很好推。

实践项目(以链接形式给出,目前在做在更新):
多项式求和(太low了。。。我写在下面自己看吧)

#include 
using namespace std;
const int MAXSIZE=5;
typedef struct
{
    int *data;
    int length;
}Sqlist;
int main()
{
    Sqlist a,b,c;
    a.data=new int;
    a.length=0;
    b.data=new int;
    b.length=0;
    for(int i=0;i<MAXSIZE;i++)
    {
        cin>>a.data[i];
        a.length++;
    }
    for(int i=0;i<MAXSIZE;i++)
    {
        cin>>b.data[i];
        b.length++;
    }
    c.data=new int;
    c.length=0;
    for(int i=0;i<MAXSIZE;i++)
    {
        c.data[i]=a.data[i]+b.data[i];
        c.length++;
    }
    for(int i=0;i<MAXSIZE;i++)
    {
        cout<<c.data[i]<<' ';
    }
    cout<<endl;
    return 0;

}

稀疏多项式的合并
图书信息管理系统

你可能感兴趣的:(数据结构)