当前位置:文档之家› 数据结构应用

数据结构应用

数据结构应用– 1. 有一个有n个结点的单链表,设计一个函数将第i-1个结点与第i个结点互换,但指针不变。

– 2. 设计一个函数,查找单链表中数值为x的结点。

– 3. 已知一个单链表,编写一个删除其值为x的结点的前趋结点的算法。

– 4. 已知一个单链表,编写一个函数从此单链表中删除自第i个元素起的length个元素。

– 5. 已知一个递增有序的单链表,编写一个函数向该单链表中插入一个元素为x的结点,使插入后该链表仍然递增有序。

– 6. 已知一个单链表,编写一个函数将此单链表复制一个拷贝。

– 7. 有一个共10个结点的单链表,试设计一个函数将此单链表分为两个结点数相等的单链表。

– 8. 与上题相同的单链表,设计一个函数,将此单链表分成两个单链表,要求其中一个仍以原表头指针head1作表头指针,表中顺序包括原线性表的第一、三等奇数号结点;另一个链表以head2为表头指针,表中顺序包括原单链表第二、四等偶数号结点。

– 9. 已知一个指针p指向单循环链表中的一个结点,编写一个对此单循环链表进行遍历的算法。

– 10. 已知一个单循环链表,编写一个函数,将所有箭头方向取反。

– 11. 在双链表中,若仅知道指针p指向某个结点,不知头指针,能否根据p遍历整个链表?若能,试设计算法实现。

– 12. 试编写一个在循环双向链表中进行删除操作的算法,要求删除的结点是指定结点p的前趋结点。

– 1. 解:本题的算法思想是:要使结点互换而指针不变,只要将两个结点的数据进行交换即可。

实现本题功能的函数如下:void exchange(node *head,int i,n){node *p,*q;int data;if(i>n)printf("error!\n");else{p=head;for(int j=1;j<i;j++)p=p->next;q=p->next;data=q->data;q->data=p->data;p->data=data;}}– 2. 解:实现本题功能的函数如下: void search(node *head,int x){node *p;p=head;while(p->data!=x && p!=NULL) p=p->next;if(p!=NULL)printf("结点找到了!\n"); elseprintf("结点未找到!\n");}– 3. 解:本题的算法思想是:先找到值为x的结点*p和它的前趋结点*q,要删除*q,只需把*p的值x 放到*q的值域中,再删除结点*p即可。

实现本题功能的函数如下:void delete(node *head,int x){ node *p,*q;q=head;p=head->next;while((p!=NULL) && (p->data!=x)){ q=p;p=p->next;}if(p==NULL)printf("未找到x!\n");else if(q==head)printf("x为第一个结点,无前趋!\n");else{q->data=x;q->next=p->next;free(p);}}– 4. 解:实现本题功能的函数如下:void deletelength(node *head,int i,int length){ node *p,*q;int j;if(i==1)for(j=1;j<=length;j++) /*删除前k个元素*/{ p=head; /*p指向要删除的结点*/head=head->next;free(p);}else{ p=head;for(j=1;j<=i-2;j++)p=p->next;/*p指向要删除的结点的前一个结点*/ for(j=1;j<=length;j++){q=p->next; /*q指向要删除的结点*/p->next=q->next;free(q);}}}– 5. 解:本题算法的思想是:先建立一个待插入的结点,然后依次与链表中的各结点的数据域比较大小,找到插入该结点的位置,然后插入该结点。

实现本题功能的函数如下:void insert(node *head,int x){node *s,*p,*q;s=(node *)malloc(sizeof(node));/*建立一个待插入的结点*/s->data=x;s->next=NULL;if(head==NULL||x<head->data)/*若单链表为空或x小于第一个结点data域*/{s->next=head; /*插入到表头后面*/head=s;}else{q=head;p=q->next;while(p!=NULL && x>p->data){q=p;p=p->next;}s->next=p; /*插入结点*/q->next=s;}}– 6. 解:本题算法的思想是依次查找原单链表(其头指针为head1)中的每个结点,对每个结点复制一个新结点并链接到新的单链表(其头指针为head2)中。

实现本题功能的函数如下:void copy(node *head1,node *head2){node *p,*q,*s;head2=(node *)malloc(sizeof(node));q=head2;q->data=head1->data;p=head1->next;while(p!=NULL){s=(node *)malloc(sizeof(node));s->data=p->data;q->next=s;q=s;p=p->next;}q->next=NULL;}– 7. 解:本题的算法思想是:在原单链表一半处将其分开,第5个结点的next域置为空,为第一个单链表的表尾。

第二个单链表的表头指针指向原单链表的第6个结点。

实现本题功能的函数如下,函数返回生成的第二个单链表的表头指针,第一个单链表仍然使用原单链表的表头指针。

node* divide(node *head1){node *head2,*prior;head2=head1;for(int i=1;i<=5;i++){prior=head2;head2=head2->next;}prior->next=NULL;return head2;}– 8. 解:本题算法的思想是将第一个链表中的所有偶数序号的结点删除,同时把这些结点链接起来构成第二个单链表。

实现本题功能的函数如下:void split(node* head1,node * head2){node *temp,*odd,*even;odd=head1;head2=head1->next;temp=head2;while(odd!=NULL && odd->next!=NULL){even=odd->next; /* even指向偶数序号的结点*/odd->next= even ->next;temp->next= even;temp= even;odd=odd->next; /*odd指向奇数序号的结点*/}even ->next=NULL;}– 9. 解:本题的算法思想是:因为是单循环链表,所以只要另设一指针q指向p用来帮助判断是否已经遍历一遍即可。

实现本题功能的函数如下:void travel(node *p){ node *q=p;while(q->next!=p){printf("%4d",q->data);q=q->next;}printf("%4d",q->data);}– 10. 解:本题算法的思想是:从头到尾扫描该循环链表,将第一个结点的next域置为NULL,将第二个结点的next域指向第一个结点,如此直到最后一个结点,便用head指向它。

由于是循环链表,所以判定最后一个结点时不能用p->next=NULL作为条件,而是用q指向第一个结点,以p!=q作为条件。

实现本题功能的函数如下:void invert(node *head){node *p,*q,*r;p=head;q=p->next;while(p!=q){r=head;while(r->next!=p)r=r->next;p->next=r;p=p->next;}q->next=head;}– 11. 解:能。

本题的算法思想是:分别从p开始沿着next以及prior向右、向左扫描直至各自的链为空即可遍历整个链表。

实现本题功能的函数如下:void travellist(node *p){ node *q;q=p;while(q!=NULL){printf("%4d",q->data);q=q->next;}q=p->prior;while(q!=NULL){printf("%4d",q->data);q=q->prior;}}– 12. 解:实现本题功能的算法如下: void deleteprior(node *p){node *pri,q;pri=p->prior;q=pri->prior;if(pri==p)printf("p结点无前趋!\n"); else{q->next=pri->next; p->prior=pri->prior; free(prior);}}。

相关主题