标签:头结点 分析 实现 .net turn 访问 取值 i++ 判断
在数据结构这门课中,数据的逻辑结构会包括线性结构和非线性结构,线性表就是线性结构的一种。根据不同的存储结构,线性表可以分为顺序表和链表。链表包括单链表、循环链表、双向链表。下面是顺序表和单链表实现的不同点的比较。
(一)初始化
顺序表:为顺序表分配一个大小确定的数组空间,空表时长度为0;
链表:构造一个空的单链表L,用头指针指向头结点,头结点的指针域置空(L = new LNode; L->next = NULL;)
(二)取值
顺序表:先判断序号值是否合理,若合理,则e = L.elem[ i - 1 ] ;
链表:用指针p指向首元结点,用j做计数器初值赋为1,从首元结点开始依次顺着链域next向下访问
p=L->next; j=1;
while(p&&j<i)
{ p=p->next; ++j; }
e = p->data;
(三)查找(按值查找)
顺序表:从第一个元素起,依次与待查找数比较,时间复杂度为O(n)
for( int i=0; i<n; i++ )
if( L.elem[i]==e) return i+1;
链表:用指针p指向首元结点,从首元结点开始依次顺着链域next向下访问,时间复杂度为O(n)
p=L->next;
while( p && p->data != e ) p=p->next;
(四)插入(在第i个位置插入新的元素e)
顺序表:将第n个至第i个位置依次向后移动一个位置,空出第i个位置,将元素e放入第i个位置,表长加1,时间复杂度为O(n)
for( int j=L.length - 1; j>=i -1; j-- ) L.elem[ j+1]=L.elem[ j ];
L.elem[ i -1 ]=e;
++L.length;
链表:先查找到第i-1个结点,再将值为e的新结点插入到结点a(i-1)和a(i)之间,时间复杂度为O(n)
p = L; j = 0;
while( p && j<i-1 ) { p=p->next; ++j; }
s = new LNode; s->data=e;
s->next = p->next; p->next = s;
(五)删除
顺序表:先判断位置i是否合理,若合理,则将被删除元素之后的元素前移,表长减1,时间复杂度为O(n)
for( j=i; j<=L.length-1; j++ ) L.elem[ j-1]=L.elem[ j ];
--L.length;
链表:先查找到第i-1个结点,临时保存被删除结点的地址以备释放,改变删除结点前驱结点的指针域,释放删除结点的指针域,时间复杂度为O(n)
while( p && j<i-1 ) { p=p->next; ++j; }
q=p-<next; p->next = q->next;
delete q;
(六)创建单链表(前插和后插)
顺序表适用于很少进行插入删除操作,经常按元素位置序号访问元素的情况;链表适用于长度变化大,频繁进行插入删除操作的情况。
刚接触到链表的时候,很陌生,面对链表的编程题是无从下手的,所以我选择了先去看看c++编程教材里的链表部分,发现书本上的代码实现的是无头结点的链表操作。于是,我上网参考了一些关于带头结点链表的操作实现代码,再结合数据结构教材里的算法分析,进一步摸索。
(参考资料:https://www.cnblogs.com/michaelGood/p/4603222.html, https://blog.csdn.net/gyh0730/article/details/78300189)
当完成实践题的时候,是要求两个线性表的交集,第一次做的时候,只用了一层循环,但是其中一个数组不能正常遍历,接着参考c++教材,用了两层循环,运行超时,最后,上课时听到老师讲解并集的算法,知道了也能用于交集,果然,结果正确了。同时,我也参考了一些关于并集和交集算法、函数sort()的资料。
(参考资料:https://www.cnblogs.com/mengqimoli/p/8604770.html, https://blog.csdn.net/l198738655/article/details/79872738)
目前遇到的困难主要是对链表的操作不很熟悉,还需要依赖书本,对于链表的实现,还需要画图才能更好的理解。接下来的目标是多练多看,争取能独立写出链表各种操作的代码。
标签:头结点 分析 实现 .net turn 访问 取值 i++ 判断
原文地址:https://www.cnblogs.com/jiminxi/p/10544803.html