数据结构 耿国华 西北大学 2-8顺序表与单链表比较和总结与提高
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
n
(a) 初始状态
p
q
L
∧
a
1
a 2
…
a
i
…
a∧
n
p 为原链表当前处理结点 断开 L->next, 使逆置表初始为空表
(b) 将单链表 L 初始为空表
q 指向原链表当前处理结点的下一 个
①
pቤተ መጻሕፍቲ ባይዱ
q
L
a1 ∧
a 2
a 3
…a i
… a∧ n
②
(c) 将 p 指向的结点插入到逆置表 L 的表头
【算法描述】
q = q->next;
}
if (r != l)
r->data = 1; /*将最后一个值域为 0 的结点的值域赋为 1*/
else
/*未找到值域为 0 的结点*/
{
temp = r->next;
s=(Node*)malloc(sizeof(Node)); /*申请新结点*/
s->data=1;
/*值域赋为 1*/
void ReverseList(LinkList L)
/*逆置带头结点的单链表 L */
{ p=L->next; /* P 为原链表的当前处理结点*/
L->next=NULL; /*逆置单链表初始为空表*/ while(p!=NULL) /*当原图单链链表表未的就处地理逆完置*/
{ q=p->next; /*q 指针保留原链表当前处理结点的下一个结点*/
s->next=temp;
r->next = s;
/*插入到头结点之后*/
r = s;
}
r = r->next;
while(r!=NULL)
/*将后面的所有结点的值域赋为 0*/
{
r->data = 0;
r = r->next;
}
}/*BinAdd 结束*/
国家精品课程 西北大学《数据结构》
1
例题:
西北大学 《数据结构》
1、
已知顺序表 L 中的数据元素类型为 int。设计算法将其调整为左右两部分,左边 的元素(即排在前面的)均为奇数,右边所有元素(即排在后面的)均为偶数, 并要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。 【问题分析】初见此题,可能会想到额外申请 1 个顺序表空间,之后依次从顺序 表 L 中选择奇数放入新表前部分,选择偶数放在新表的后半部分。但是题目要求 空间复杂度为 O(1),很显然上述方法是不可行的。既然要求空间复杂度为 O(1), 说明只能借助 1 个辅助空间。分析题目要求,其实我们只需要将位于表左半部分 的偶数与位于表右半部分的奇数通过一个辅助变量进行交换即可,为此我们可 以设置两个位置指示器 i 和 j,i 初值为 0,j 初值为 L->last,当 L->elem[i]为偶数, L->elem[j]为奇数时,则将 L->elem[i] 与 L->elem[j]交换;否则,L->elem[i]为奇 数,i++, L->elem[j]为偶数,j++。这样既可以保证算法的时间复杂度为 O(n),亦可 保证空间复杂度为 O(1)。 【算法描述】 AdjustSqlist(SeqList *L) /* { int i=0,j=L->last; while(i<j) { while(L->elem[i]%2!=0)
访问到 a1,a2,a3…an-1,an;2)我们可以借鉴前面讲到过的头插入法建链表的方 法,因为头插入法建链表又称为逆序建表法 3)唯一不同的是,我们不需要 重新申请结点空间,而只需要从原有单链表上依次“摘下”结点,之后插入 到单链表头结点和表中第一个结点之间即可。如图所示
L
a 1
a 2
…
a
i
…
a∧
void BinAdd(LinkList l) /*用带头结点的单链表 L 存储二进制数,实现加 1 运算*/
{ Node *q,*r,*temp,*s;
3
课外作业
q=l->next;
r=l;
while(q!=NULL) /*查找最后一个值域为 0 的结点*/
{
if(q->data == 0)
r = q;
例题
第二章性线性表 第一节
} }/*end of AdjustSqlist*/
-1-
课外作业
2、
算法实现带头结点单链表的就地逆置问题。
【问题分析】逆置就是使得表中内容由原来的( a1,a2,…,ai-1,ai,ai+1, …,an)变为(an,an-1,…,ai+1,ai,ai-1, …,a1)。就地逆置就是不需要额 外申请结点空间,只需要利用原有的表中的节点空间。若对顺序表中的元素进行 逆置,可以借助于“交换”前后相应元素;对单链表中的元素进行逆置,则不 能按“交换”思路,因为对于链表中第 i 个结点需要顺链查找第 n-i+1(链表长度 为 n)个结点,逆置链表的时间复杂度将达 O(n2)。 算法思路:逆置后的单链表初始为空,表中的结点不是新生成的,而是从原链 表中依次“删除”,再逐个头插入到逆置表中(类同算法 2.5 头查法创建链 表)。设逆置链表的初态为空表,“删除”已知链表中的第一个结点,然后将它 “插入”到逆置链表的“表头”,即使它成为逆置链表中“新”的第一个结点, 如此循环,直至原链表为空表止。 1) 根据单链表的特点,通过头指针 L 我们可以顺着每个结点的 next 域,依次
p->next=L->next; L->next=p; /*将当前处理结点 p 插入到逆置表 L 的表头*/
p=q;
/*p 指向下一个待插入的结点*/
} /*end of while*/
}/*end of ReverstList*/
3、
建立一个带头结点的线性链表,用以存放输入的二进制数,链表中每个结点的 data 域存放一个二进制位。并在此链表上实现对二进制数加 1 的运算 。 【问题分析】①建链表:带二进制数可用带头结点的单链表存储,第一个结点存 储二进制数的最高位,依次存储,最后一个结点存储二进制数的最低位。 ②二进制加法规则:实现二进制数加 1 运算,方向从低位往高位找到第一个值 为 0 的位,从该位开始,对后面所有低位进行求反运算。③链表实现二进制加 1 时,从高位往低位与运算方向正好相反,从第一个结点开始找,找出最后一个 值域为 0 的结点,把该结点值域赋为 1,其后所有结点的值域赋为 0。④若在链 表中未找到值域为 0 的结点,则表示该二进制数各位均为 1,此时,申请一新结 点,值域为 1,插入到头结点与原链表的第一个结点之间,成为新链表的第一 个结点,其后所有结点的值域赋为 0。 【算法描述】
i++; /*从表的左半部分开始检测,若为奇数,则 i 加 1,直到找到偶数为止*/ while(L->elem[j]%2= =0) j--;/* 从表的右半部分开始检测,若为偶数,则 j 减 1,直到找到奇数为止*/
if(i<j) {t= L->elem[i]; L->elem[i]= L->elem[j]; L->elem[j]=t; }/*交换*/