2006-2007-1 - 数据结构讲义-重修

2026/4/27 19:49:53

{ int i;

i=space[S].next;

while (i) { cout<

void main() {

SLList space;

ElemType A[]={1,2,3,4}, B[]={2,4,6,8,10}; int S;

difference(space,S,4,5,A,B); SLListOutput(space,S); }

2.3.2 循环链表

循环链表(circular linked list)的最后一个结点的指针域指向头结点,整个链表形成一个环。从表中任一结点出发均可找到表中其它结点。循环链表的操作和线性链表基本一致,差别是最后结点的不是next==NULL,而是next等于头指针。

L a b c L [习题2.33③]将线性链表分割为3个循环链表。

void SplitLList(LList L, LList &A, LList &B,LList &C) {

LList p,q;

A=new LNode; A->next=A; B=new LNode; B->next=B; C=new LNode; C->next=C; p=L->next; while (p) {

q=p; p=p->next;

if (q->data>='a' && q->data<='z' ||q->data>='A' && q->data<='Z') { q->next=A->next; A->next=q;} else if (q->data>='0' && q->data<='9') { q->next=B->next; B->next=q;} else { q->next=C->next; C->next=q;} } delete L; }

2.3.3 双向链表

双向链表(double linked list)的结点中有两个指针域,分别指向直接后继和直接前趋。在C语言中描述如下: typedef struct DLNode {

ElemType data; DLNode *prior,*next; } *DLList;

双向循环链表,如图2.14(c)所示,链表中存有两个环,图2.14(b)所示为只有一个表头结点的空表。

L a b 第15页

在双向链表中,若d为指向表中某一结点的指针,则有 d->next->prior==d->prior->next==d 这个表示式恰当地反映了这种结构的特性。

在双向链表中,有些操作如:ListLength、GetElem、LocateElem等仅需涉及一个方向的指针,则它们的算法描述和线性链表的操作相同,但在插入、删除时不同,在双向链表中需同时修改两个方向上的指针,它们的算法分别如算法2.18和2.19所示。

//取双向循环链表的元素的位置指针 DLList ListGetElem(DLList L,int i) {

DLList p; int j; p=L; j=0;

while (p->next!=L && jnext; j++; } if (i<1 || j

// 在双向循环链表中插入第i个结点(参见算法2.18) bool ListInsert(DLList &L, int i,ElemType e) {

DLList p,s;

p=ListGetElem(L,i-1); if (!p) return false;

s=new DLNode; s->data=e; s->next=p->next; p->next->prior=s; p->next=s; s->prior=p; return true; }

void ListInsertLast(DLList &L, ElemType e) {

DLList s;

s=new DLNode; s->data=e;

s->prior=L->prior; L->prior->next=s; s->next=L; L->prior=s; }

void ListInsertFirst(DLList &L, ElemType e) {

DLList s;

s=new DLNode; s->data=e; s->next=L->next; L->next->prior=s; s->prior=L; L->next=s; }

// 算法 2.19 在双向循环链表中删除元素

bool ListDelete(DLList &L,int i,ElemType &e){ DLList p;

p=ListGetElem(L,i); if (!p) return false; e=p->data; p->prior->next=p->next;

第16页

p->next->prior=p->prior; delete p; return true; }

//建立双向循环链表

void ListCreate(DLList &L, ElemType a[ ],int n){ int i;

L=new DLNode; L->prior=L; L->next=L;

for (i=n; i>=1; i--) ListInsertFirst(L,a[i-1]); }

//遍历双向循环链表

void ListTraverse(DLList L,void visit(ElemType)) { DLList p; p=L->next;

while (p!=L) { visit(p->data); p=p->next; } }

[习题2.38] 按访问频度降序排序。 struct ElemType

{ char name[6+1]; char tele[7+1]; int freq; };

void visit(ElemType e) {

cout<

void ListCreate(DLList &L,char fn[]) { //建立双向循环链表

ElemType e; ifstream ft;

L=new DLNode; L->prior=L; L->next=L;

ft.open(fn,ios::nocreate); if (!ft) return; while (!ft.eof()) {

ft>>e.name>>e.tele;

e.freq=0; ListInsertFirst(L,e); }

ft.close(); }

DLList ListVisit(DLList &L, char name[7]) {

DLList p,q; p=L->next;

while (p!=L && strcmp(p->data.name,name)) p=p->next; if (p==L) return NULL; p->data.freq++; q=p;

while (q->prior!=L && q->prior->data.freqdata.freq) q=q->prior; // 算法1 交换数据

ElemType e=q->data; q->data=p->data; p->data=e; return q;

// 算法2 将p前移,将p插在q->prior与q之间,有可能q==p if (p==q) return p; p->prior->next=p->next; p->next->prior=p->prior; DLList r=q->prior;

r->next=p; p->prior=r;

p->next=q; q->prior=p; return p; }

第17页

在链表中,结点之间的关系用指针来表示,则数据元素在线性表中的位序概念已淡化,而元素在链表中的位置所代替。因此可从实际应用的角度出发重新定义线性链表及其基本操作。

typedef struct LNode {

ElemType data; LNode *next; } *Link,*position; typedef struct {

Link head,tail; int len; } LinkList;

基本操作见课本第37-38页。

2.4 一元多项式的表示及相加

本节内容是线性表的一个应用例子。 一元多项式

pn(x)可按升幂写成:

?(p0,p1,p2,?,pn)

pn(x)?p0?p1x?p2x2???pnxn

它由n+1个系数唯一确定。它可用一个线性表P来表示: P每一项的指数i隐含在其系数P的序号里。

对于稀疏多项式,如:S(x)系数和指数。

一元n次多项式若只写出系数非0的项,则可写成 其中,

?1?3x10000?2x20000,若储存全部系数则严重浪费内存空间,而应该只存储非零项的

pn(x)?p1xe1?p2xe2???pmxem pi是指数为

ei的项的非零系数,且满足:0

?e1?e2???em?n,可用线性表

?(p1,e1),(p2,e2),?,(pm,em)?表示多项式pn(x)。

抽象数据类型一元多项式的定义如下: ADT Polynomial {

数据对象:D={ai|ai∈TermSet,i=1..m}

TermSet中的每个元素包含一个表示系数的实数和表示指数的整数。 数据关系:R1={|ai-1,ai∈D,且ai-1中指数

[例2.4]抽象数据类型Polynomial的实现。基本操作的函数原型说明见课本第42-43页。

[例]一元多项的加法。加法运算规则:两个多项式中所有指数相同的项,对应系数相加,若和不为零,则构成和多项式中的一项;若和为零,则和多项式中没有此项。所有指数不相同的项均复制到“和多项式”中。同时参考课本算法2.23.

#include \struct ElemType {

float coef; int exp; //coefficient, exponent };

void visit(ElemType e) { cout<<\

#include \

void AddPolynomial(LList &A, LList &B)

第18页


2006-2007-1 - 数据结构讲义-重修.doc 将本文的Word文档下载到电脑
搜索更多关于: 2006-2007-1 - 数据结构讲义-重修 的文档
相关推荐
相关阅读
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 10

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219