赞
踩
问题:《数据结构与算法分析(C++语言版)》p58 五、2
已知一个如下图所示的带头结点的单链表head(注:若头指针名是head,则把单链表称为表head),其存储结构为:
typedef struct Lnode{
ElemType data;
struct Lnode *next;
}Lnode,*LinkList;
请编写一个线性表的转置算法。线性表转置是指将(a1,a2,...,an) ( a 1 , a 2 , . . . , a n )变为(an,an−1,...,a1) ( a n , a n − 1 , . . . , a 1 )。
问题分析
程序代码
运行结果
在原链表中区别对待第一次操作的正确输出:
在原链表中未区别对待第一次操作的错误输出:
注意事项
问题分析
根据题意,首先要创建一个带头结点的单链表,单链表包含头结点,每个结点包括数据与data和指针域*next,为了简化操作,可设单链表的元素为数字1~10,为此需要创建初始化单链表的函数,首先将头结点指向NULL,然后用循环连续创建10个新结点,并将他们依次相连,并赋值;为了能够显示出转置前后的区别,需要编写一个打印函数,需要从首元结点(Head->next)依次遍历到最后一个结点(p->next=NULL),并用cout语句输出,注意需要加上分隔符;最后为了实现该题的核心功能,需要创建一个转置函数(Reverse),其中需考虑第一次操作与后续操作不同的情况,否则会出现第一个结点(即转置后的最后一个结点)出现自己指向自己的死循环;最后在主程序中调用相应的函数,可以选择在原单链表进行操作,也可重新建立一个单链表进行操作。
程序代码
#include
#include
#define ElemType int
using namespace std;
typedef struct Lnode{
ElemType data;
struct Lnode *next;
}Lnode,*LinkList;
int InitList(LinkList h) {
Lnode *p;
h->next=NULL;//初始化头结点
for(int i=0; i<10; i++) {
p=new Lnode;
p->data=i+1;//依次加一
p->next=NULL;
h->next=p;
h=p;
}p->next=NULL;//最后指向空
}
int ListPrint(LinkList h) {
h=h->next;//指向首元结点
while(h) {
cout
h=h->next;
}
cout
Lnode *p,*q;
int j=0;//计数器,用来区别第一次操作和后续操作
p=h->next;
while(p!=NULL){
q=p->next;//q结点指向p结点的后一个
if(j==0)//如果是第一次操作
p->next=NULL;//首个结点(转置后的最后一个结点)指向空,避免打印时出现死循环
else
p->next=h->next;//指向新的首元结点
h->next=p;//首元结点指向新的结点,即把位序更大的元素挪到前面
p=q;//结点后移
j++;//计数器+1
}
}
int main() {
Lnode *head,*head2,*a,*b;
InitList(head);
ListPrint(head);
Reverse(head);
ListPrint(head);
//head2=new Lnode; 使用新的单链表进行存储
// a=head->next;
// head2->next=NULL;
// while(a){
// b=a->next;
// a->next=head2->next;
// head2->next=a;
// a=b;
// }
// a=head2->next;
// ListPrint(head2);
}
运行结果
在原链表中区别对待第一次操作的正确输出:
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
在原链表中未区别对待第一次操作的错误输出:
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ……
注意事项
也可以在Reverse函数中不使用计数器j,即需要先对第一次循环特别操作,让第一个结点先指向NULL,然后再将后续的操作进入循环。
使用新的单链表进行存储时,则不需要进行特殊操作,因为新链表的头指针本来指向的就是NULL,所以把原来链表的元素插入进去不会产生死循环的现象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。