数据结构常用算法实现print文档格式.docx
《数据结构常用算法实现print文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构常用算法实现print文档格式.docx(49页珍藏版)》请在冰豆网上搜索。
![数据结构常用算法实现print文档格式.docx](https://file1.bdocx.com/fileroot1/2023-2/3/a0e8fa2f-97fe-4df6-9dc5-dfdfdf699b39/a0e8fa2f-97fe-4df6-9dc5-dfdfdf699b391.gif)
11}
12voidinsert(intpos,ELEMTYPEitem)
13{
14inti;
15for(i=l.length;
i>
pos;
i--)
16l.listarray[i]=l.listarray[i-1];
17l.listarray[pos]=item;
18l.length++;
19}
20voidappend(ELEMTYPEitem)
21{
22l.listarray[l.length++]=item;
24}
25ELEMTYPEdelete(intpos)
26{
27inti;
28ELEMTYPEtemp;
29temp=l.listarray[pos];
30for(i=pos;
i<
l.length-1;
i++)
31l.listarray[i]=l.listarray[i+1];
32l.length--;
33returntemp;
}
35intlength()
{
37returnl.length;
}
39intfind(ELEMTYPEitem)
40{inti;
42for(i=0;
l.length;
43if(l.listarray[i]==item)
44returni;
45return-1;
47voidprint()
48{inti;
50for(i=0;
51printf("
%d"
l.listarray[i]);
52printf("
\n"
);
54voidmain()
55{clrscr();
57clear();
58append(10);
/*Lis10*/
59append(20);
/*Lis(10,20)*/
60append(30);
/*Lis(10,20,30)*/
61print();
62insert(2,15);
/*Lis(10,20,15,30)*/
63print();
64printf("
\n%d"
find(100));
65printf("
\n%d\n"
delete(3));
/*Lis(10,20,15)*/
66print();
线性表的链式表示
程序2_2.c提供了链式存储结构下线性表的实现。
第3行到第8行包含了线性表中结点的说明,其中element表示数据域,存放该结点的数据信息,next为指针域,指明该结点的唯一后继结点在内存中的存放地址,或是在该结点序列中所在的物理位置。
线性链表由head和tail表示。
接下来从第9行到第76行线性表运算函数的定义。
第9行到第14行初始化单链表。
head指针与tail指针指向表头结点。
在单链表的最后一个结点后插入一个结点只要将单链表尾指针tail指向新插入结点,新插入结点成为最后一个结点即可。
第15行到第20行函数append实现追加一个新结点到单链表的最后,新结点的元素值为item。
malloc是C语言提供的标准函数,其功能是申请存储空间。
设p是指向单链表中一个结点的指针,在p指向的结点后面插入一个结点包括三个步骤。
首先,要创建一个新的结点,并且赋给它一个新的值。
其次,新结点的next指向指针p指向结点的后继结点。
第三,指针p指向的结点的next要指向新插入的结点。
第21行到第38行函数insert实现在单链表的第i个结点前面插入一个新结点。
新结点的元素值为item,s为指向新结点的指针。
算法在实现时,首先查找新结点插入位置,然后根据上面所述修改相应指针。
从单链表删去一个结点只需将被删结点的前趋结点的next域指向被删结点的后继结点即可。
但必须注意,被删结点占据的内存空间应该返回给存储器。
因此可设一个临时指针指向要删去的结点,而后调用C语言提供的标准过程free将被删去的结点占据的内存空间返回给存储器。
第39行到第57行的函数delete实现删除结点运算。
第58行到第65求单链表中所含结点的个数。
为求单链表的结点个数,我们必须从单链表表头开始,沿着每个结点的链指针,依次向后访问并计数,直到最后一个结点位置。
程序2_2.c
1#include<
alloc.h>
4ELEMTYPEelement;
5structlist*next;
7structlist*head;
8structlist*tail;
9voidinit()
10{
11head=malloc(sizeof(structlist));
12head->
next=NULL;
13tail=head;
14}
15voidappend(ELEMTYPEitem)
16{
17tail=tail->
next=(structlist*)malloc(sizeof(structlist));
18tail->
element=item;
19tail->
20}
21intinsert(intpos,ELEMTYPEitem)
22{
23structlist*p,*s;
24intj;
25s=(structlist*)malloc(sizeof(structlist));
26s->
27p=head;
28j=1;
29while((p!
=NULL)&
&
(j<
pos)){
30p=p->
next;
31j++;
32}
33if((!
p)||(j>
pos))return0;
34s->
next=p->
35p->
next=s;
36if(tail==p)tail=s;
37return1;
38}
39ELEMTYPEdelete(intpos)
40{
41structlist*p,*q;
42ELEMTYPEtemp;
43intj;
44q=p;
p=head->
45j=1;
46while((p!
47q=p;
p=p->
48j++;
49}
50if((!
pos))
51return0
52q->
53temp=p->
element;
54if(tail==p)tail=q;
55free(p);
56returntemp;
57}
58intlength()
59{
60structlist*p;
61intcnt=0;
62for(p=head->
p!
=NULL;
p=p->
next)
63cnt++;
64returncnt;
65}
66intfind(ELEMTYPEitem)
67{
68structlist*p=head->
69while(p!
=NULL){
70if(p->
element==item)
71return1;
72else
73p=p->
74}
75return0;
76}
77voidprint()
78{
79structlist*p;
80printf("
81for(p=head->
p!
=NULL;
p=p->
82printf("
p->
element);
83}
84voidmain()
85{
86clrscr();
87init();
88append(10);
/*listis(10)*/
89append(20);
/*listis(10,20)*/
90append(30);
/*listis(10,20,30)*/
91append(40);
/*listis(10,20,30,40)*/
92insert(3,35);
/*listis(10,20,30,35,40)*/
93print();
94printf("
delete(4));
/*listis(10,20,30,35)*/
95print();
96}
栈
程序2_3.c是栈数据结构的实现,第3行到第6行包含栈类型的说明,top被定义为表示栈中最上面那个元素的位置。
push(第13行到第17行)和pop(第18行到第22行)只是从top指示的数组中的位置插入和删去一个元素,因为top表示栈顶元素的位置,所以push首先把一个值插入到栈顶位置,然后把top加1。
同样,pop首先把top减1,然后删去栈顶元素。
函数topValue(第23行到27行)只是将栈顶元素返回。
如果栈中没有元素,函数isEmpty(第28行到第31行)返回1,否则返回0。
程序2_3.c
#include<
assert.h>
#include<
stdio.h>
#defineMAXSIZE100
typedefintELEMTYPE;
structstack{
ELEMTYPElistarray[MAXSIZE];
inttop;
};
structstacks;
voidinit()
s.top=0;
voidpush(ELEMTYPEitem)
assert(s.top<
MAXSIZE);
s.listarray[s.top++]=item;
ELEMTYPEpop()
intisEmpty();
assert(!
isEmpty());
returns.listarray[--s.top];
ELEMTYPEtopValue()
returns.listarray[s.top-1];
intisEmpty()
returns.top==0;
voidmain()
init();
push(10);
/*sis(10)*/
push(20);
/*sis(20,10)*/
printf("
%d"
topValue());
/*returntopelement20*/
pop());
程序2_4.c给出了链式栈表示和各种运算的算法。
其中top是指向链式栈第一个结点(栈顶)的指针。
进栈操作(第13行到第21行)首先申请一个新结点,并初始化该结点,然后修改新产生的结点的next域指向栈顶,并设置top指向新的链表结点。
第22行到第32行是出栈操作。
变量temp用来存储栈顶结点的值,ltemp用于在删去栈顶结点时保持与栈的链接,它指向当前栈顶链接到的结点。
此时把原来的栈顶结点释放回内存,恢复top等于ltemp。
也就是指向原来栈顶链接的结点,原来栈顶的值temp作为pop函数的返回值。
程序2_4.c
malloc.h>
structnode{
ELEMTYPEelem;
structnode*next;
structnode*top;
top=NULL;
structnode*p;
if((p=(structnode*)malloc(sizeof(structnode)))!
=NULL){
p->
elem=item;
next=top;
top=p;
ELEMTYPEtemp;
structnode*ltemp;
temp=top->
elem;
ltemp=top->
free(top);
top=ltemp;
returntemp;
returntop->
returntop==NULL;
push(30);
/*sis(30,20,10)*/
%d\n"
/*sis(20,10)*/
队列
在程序2_5.c中,q表示循环队列(第3行到第9行),其队头与队尾指示变量分别为front和rear。
队列中的元素类型为int(第3行)。
函数enqueue(第14行到第19行)执行队列的插入操作,参数item是插入队列的元素。
当队列不满时,enqueue首先移动队尾指针,然后将item置入rear所指位置。
函数dequeue(第20行到25行)执行队列的删除操作,返回从队列中取出的元素。
函数firstValue(第26行到第30行)返回队列头元素。
程序2_5.c
structqueue{
intfront;
intrear;
ELEMTYPEelem[MAXSIZE];
structqueueq;
q.front=q.rear=0;
voidenqueue(ELEMTYPEitem)
assert(((q.rear+1)%MAXSIZE)!
=q.front);
q.rear=(q.rear+1)%MAXSIZE;
/*incrementrear*/
q.elem[q.rear]=item;
ELEMTYPEdequeue()/*dequeueelementfrofrontofqueue*/
/*theremustbesomethingtodequeue*/
q.front=(q.front+1)%MAXSIZE;
/*incrementfront*/
returnq.elem[q.front];
/*returnvalue*/
ELEMTYPEfirstValue()/*getvalueoffrontelement*/
returnq.elem[(q.front+1)%MAXSIZE];
intisEmpty()/*TRUEisqueueisempty*/
returnq.front==q.rear;
enqueue(10);
/*qis(10)*/
enqueue(20);
/*qis(10,20)*/
enqueue(30);
/*qis(10,20,30)*/
firstValue());
/*willdisplay10*/
dequeue());
/*willdispla10*/
程序2_6.c给出了链式队列的说明和函数的实现。
front和rear分别是指向队首和队尾元素的指针。
链式队列的实现不需要表头结点,当队列为空时,指针front和rear的值均为空(NULL)。
当在队列中插入一个结点时(第14行到27行),新结点链入rear所指结点的next域,并使rear指向新的结点。
如果在插入之前队列为空,则指针front指向新插入的结点。
当从队列中删除一个结点时(第28行到37行),要把front所指结点的next域的值赋给front,并且释放这个结点。
如果删除之后队列为空,则置指针rear为空(NULL)。
程序2_6.c
structnode*front;
structnode*rear;
rear=front=NULL;
if(rear!
=NULL){
rear->
next=(structnode*)malloc(sizeof(structnode));
next->
rear=rear->
else{
front=rear=(structnode*)malloc(sizeof(structnode));
front->
ELEMTYPEdequeue()
ELEMTYPEtemp=front->
structnode*ltemp=front;
front=front->
free(ltemp);
if(front==NULL)rear=NULL;
ELEMTYPEfirstValue()
returnfront->
returnfront==NULL;
稀疏矩阵
程序3_1.c是按照快速转置算法求矩阵的转置。
程序第2行给出稀疏矩阵a的三元组表表示。
函数FastTranspose按照快速转置算法思想将稀疏矩阵a转置为稀疏矩阵b,b也表示为三元组表形式。
第11行到第13行计算矩阵a的每一列的非零元素个数。
第15行计算a中每一列第一个非零元素在b中的起始位置。
第16行第22行对a中的元素依此进行转置。
程序3_1.c
1#defineMAXCOL100
2inta[][3]={{7,6,8},{0,0,5},{0,3,2},{0,5,8},{1,1,6},
{1,2,9},{2,3,3},{4,0,9},{5,2,2}};
3intb[9][3];
4FastTranspose(inta[][3],intb[][3])
5{
6int