数据结构第一次小结

数据结构

一、思维导图

二、重要概念的笔记

1、顺序存储结构中只需存放元素自身的信息,因此,存储密度大,空间利用率高
2、顺序表的元素位置可以用元素的下标通过简单的解析式计算出来,所以可以随机存取元素。
3、单链表:在每个结点中包含有数据域外,只设置一个指针域,用于指向其后继结点。
4、双链表:在每个结点中包含有数值域外,设置有两个指针域,分别用于指向其前驱结点和后继结点。
5、循环链表:循环链表是另一种形式的链式存储结构。它的特点是表中尾结点的指针域不变,而是指向表头结点,整个链表形成一个环
6、栈:进栈: Push(S,x)、可形象地理解为压入,这时栈中会多一个元素。
退栈: Pop(S) 、 可形象地理解为弹出,弹出后栈中就无此元素了。
取栈顶元素:StackTop(S),不同与弹出,只是使用栈顶元素的值,该元素仍在栈顶不会改变。
7、 可以用栈来转换一些递归函数。
8循环队列判断队空条件:

r.front==r.rear;

判断队满的条件:

r.front==(r.rear+1)%MaxSize;

三、疑难问题及解决方案

1、计算next[j]函数以及nextval[j]的值;
解决方案:刚开始由于概念过于抽象导致无法理解,后面通过多次画图以及课堂上的练习从而掌握;
其做法如下:KMP算法的关键在于求算next[]数组的值,即求算模式串每个位置处的最长后缀与前缀相同的长度,下面按照递推的思想总结一下求解next[]数组:
   根据定义next[1]=0,假设next[j]=k, 即P[1..k-1] == P[j-k,j-1]
   1)若P[j] == P[k],则有P[1..k] == P[j-k,j],很显然,如果next[j]=k; 则next[j+1]=next[j]+1=k+1;否则next[j+1]=k+1!=next[j]+1;(当初就想着记公式简单可以直接套用呢,结果只记住next[j+1]=next[j]+1以至于后来迷糊了)
   2)若P[j]!=P[k],则可以把其看做模式匹配的问题,即匹配失败的时候,k值如何移动,显然k=next[k];
然后在根据next值求nextval;
部分代码如下:

void getNext(char *p,int *next)
{
    int j,k;
    next[1]=0;
    j=1;
    k=0;
    while(j<strlen(p)-1)
    {
        if(k==0||p[j]==p[k])    //匹配的情况下,p[j]==p[k],next[j+1]=k+1;
        {
            j++;
            k++;
            next[j]=k;
        }
        else                   //p[j]!=p[k],k=next[k]
            k=next[k];
    }
}
/* 求模式串T的next函数修正值并存入数组nextval */
void get_nextval(String T, int *nextval) 
{
  	int i,j;
  	i=1;
  	j=0;
  	nextval[1]=0;
  	while (i<T[0])  /* 此处T[0]表示串T的长度 */
 	{
    	if(j==0 || T[i]== T[j]) 	/* T[i]表示后缀的单个字符,T[j]表示前缀的单个字符 */
	{
      		    ++i;  
	            ++j;  
		if (T[i]!=T[j])      /* 若当前字符与前缀字符不同 */
		        nextval[i] = j;	/* 则当前的j为nextval在i位置的值 */
      		else 
			nextval[i] = nextval[j];	/* 如果与前缀字符相同,则将前缀字符的 */
							/* nextval值赋值给nextval在i位置的值 */
    	} 
	else 
		j= nextval[j];			/* 若字符不相同,则j值回溯 */
  	}
}
posted @ 2020-03-28 16:48  林毅()  阅读(101)  评论(0编辑  收藏  举报