c语言数据结构单链表的转置,数据结构与算法-单链表-线性表转置

问题:《数据结构与算法分析(C++语言版)》p58 五、2

已知一个如下图所示的带头结点的单链表head(注:若头指针名是head,则把单链表称为表head),其存储结构为:

typedef struct Lnode{

ElemType data;

struct Lnode *next;

}Lnode,*LinkList;

e5c1bb9c410df02b7fc76d3b127535dd.png

请编写一个线性表的转置算法。线性表转置是指将(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,所以把原来链表的元素插入进去不会产生死循环的现象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值