c语言数据结构单链表的转置,实验二 单链表的合并拆分与转置

本文介绍了链表的实现,包括线性链表的合并、拆分和逆置等操作。通过C++实现了一个模板化的单链表类,提供了插入、删除、查找等基本操作,并详细展示了合并两个链表、原地逆置链表以及将链表分为奇偶部分的算法。实验过程强调了对链表特性的理解和运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【实验简介】链表是用链接存储的方式来表达线性表,它用指针表示结点间的逻辑关系,链表适用于插入或删除频繁,存储空间需求不定的情形。

【实验内容】定义一个链表存储的线性表,除已给出的表元素插入、删除、查找等基本操作外,再提供表的合并、拆分和逆置等操作。在应用程序中建立两个整型的单链表对象A和B,应用线性表的基本操作对表的实例对象进行操作测试。

1.

设线性链表A=(a1,a2,…,am),,B=(b1,b2,…bm),按下列规则合并A,B为线性表C的算法,即使得

C = (a1,b1,…,am,bm, b

(m+1),…,bn) 当m<=n

C

= (a1,b1,…,an,bn,a(n+1),…,am)当m>n

C表利用A表和B表中的结点空间构成。

2. 将C表原地逆置。

3. 将C表的中偶数和奇数分别链接为两个循环链表D和E。

说明:每一次合并、拆分和逆置等操作的结果均要输出。

【主要代码】

单链表头文件:LinkedList.h

#ifndefLINKEDLIST_H

#defineLINKEDLIST_H

#include

#include"LinkNode.h"

template

classLinkedList

{

public:

LinkedList(){first =

newLinkNode;}

//默认构造函数

LinkedList(const T

&x){first =

newLinkNode(x);}

//带形参的构造函数

LinkedList(LinkedList

&L); //复制构造函数

~LinkedList(){makeEmpty();}

//析构函数

void makeEmpty();

//将表置空

int Length()const;

//求表长度

LinkNode

*getHead()const {returnfirst;} //取表头结点指针

LinkNode

*Search(T x); //搜索数据域为x的结点

LinkNode

*Locate(int i)const; //取i号表项的地址

bool getData(int i,T

&x)const; //取i号表项的数据

void setData(int i,T

&x); //用x修改第i个元素的值

bool Insert(int i,T

&x); //在第i个元素后插入x

bool Remove(int i,T

&x); //删除第i个元素,x返回该元素的值

bool IsEmpty()const

//判断表空否,空则返回true

{

returnfirst->link==NULL?true:false;

}

void Output();

//输出

void Turn();

//将单链表的指向倒转

void

Combine(LinkedList&A,LinkedList

&B); //将两个单链表合并

void

Divide(LinkedList&D,LinkedList

&E);

protected:

LinkNode

*first;

};

template

//复制构造函数实现

LinkedList::LinkedList(LinkedList&L)

{

T value;

LinkNode *srcptr

= L.getHead();

LinkNode

*destptr = first =

newLinkNode;

while

(srcptr->link!=NULL)

{

value =

srcptr->link->data;

destptr->link =

newLinkNode(value);

srcptr =

srcptr->link;

destptr =

destptr->link;

}

destptr->link =

NULL;

}

template

//置空函数实现

voidLinkedList::makeEmpty()

{

LinkNode

*p;

while

(first->link!=NULL)

{

p =

first->link;

first->link =

p->link;

delete p;

}

}

template

//求长函数实现

intLinkedList::Length()const

{

LinkNode *p =

first->link;

int count =

0;

while

(p!=NULL)

{

p =

p->link;

count++;

}

return

count;

}

template

//搜索函数实现

LinkNode*LinkedList::Search(T

x)

{

LinkNode

*current =first->link;

while

(current!=NULL)

{

if

(current->data==x)

break;

else

current =

current->link;

return

current;

}

}

template

//定位函数实现

LinkNode*LinkedList::Locate(int

i)const

{

if

(i<0)

return NULL;

LinkNode

*current = first;

int k = 0;

while

(current!=NULL&&k

{

current =

current->link;

k++;

}

return

current;

}

template

//取值函数实现

boolLinkedList::getData(int

i,T &x)const

{

if

(i<=0)

return NULL;

LinkNode

*current = Locate(i);

if

(current==NULL)

return

false;

else

{

x =

current->data;

return true;

}

}

template

//修改函数实现

voidLinkedList::setData(int

i,T &x)

{

if

(i<=0)

return;

LinkNode

*current = Locate(i);

if

(current==NULL)

return;

else

current->data =

x;

}

template

//插入函数实现

boolLinkedList::Insert(int

i,T &x)

{

LinkNode

*current = Locate(i);

if

(current==NULL)

return

false;

LinkNode

*newNode =

newLinkNode(x);

newNode->link =

current->link;

current->link =

newNode;

return true;

}

template

//删除函数实现

boolLinkedList::Remove(int

i,T &x)

{

LinkNode

*current = Locate(i-1);

if(current==NULL||current->link==NULL)

return

false;

LinkNode *del

=current->link;

x =

del->data;

delete del;

return true;

}

template

//输出函数实现

voidLinkedList::Output()

{

LinkNode

*current =first->link;

while

(current!=NULL)

{

cout<data<

current =

current->link;

}

cout<

}

template

//倒置函数实现

voidLinkedList::Turn()

{

if

(first->link==NULL)

return;

LinkNode

*current1 =first->link,*current2 =

first->link->link;

LinkNode

*p;

while(p!=NULL)

{

p =

current2->link;

current2->link

= current1;

current1 =

current2;

current2 =

p;

}

first->link->link =

NULL;//让倒置后的最后一个结点的指针域为空

first->link =

current1;//让附加的表头结点的指针域指向第一个结点

}

template

voidLinkedList::Combine(LinkedList

&A,LinkedList&B)

//合并函数

{

T

value1,value2;

LinkNode

*srcptr1 = A.getHead();

LinkNode

*srcptr2 = B.getHead();

LinkNode

*destptr = first =

newLinkNode;

if

(A.Length()

{

while

(srcptr1->link!=NULL)

{

value1

=srcptr1->link->data;

value2

=srcptr2->link->data;

destptr->link =

newLinkNode(value1);

srcptr1 =

srcptr1->link;

destptr =

destptr->link;

destptr->link =

newLinkNode(value2);

srcptr2 =

srcptr2->link;

destptr =

destptr->link;

}

while

(srcptr2->link!=NULL)

{

value2 =

srcptr2->link->data;

destptr->link =

newLinkNode(value2);

srcptr2 =

srcptr2->link;

destptr =

destptr->link;

}

destptr->link =

NULL;

}

if

(A.Length()==B.Length())

{

while

(srcptr2->link!=NULL)

{

value1

=srcptr1->link->data;

value2 =

srcptr2->link->data;

destptr->link =

newLinkNode(value1);

srcptr1 =

srcptr1->link;

destptr =

destptr->link;

destptr->link =

newLinkNode(value2);

srcptr2 =

srcptr2->link;

destptr =

destptr->link;

}

destptr->link =

NULL;

}

if

(A.Length()>B.Length())

{

while

(srcptr2->link!=NULL)

{

value1

=srcptr1->link->data;

value2

=srcptr2->link->data;

destptr->link =

newLinkNode(value1);

srcptr1 =

srcptr1->link;

destptr =

destptr->link;

destptr->link =

newLinkNode(value2);

srcptr2 =

srcptr2->link;

destptr =

destptr->link;

}

while

(srcptr1->link!=NULL)

{

value1

=srcptr1->link->data;

destptr->link =

newLinkNode(value1);

srcptr2 =

srcptr2->link;

destptr =

destptr->link;

}

destptr->link =

NULL;

}

}

template

voidLinkedList::Divide(LinkedList

&D,LinkedList&E)

{

T value;

LinkNode *srcptr

=this->getHead();

LinkNode

*destptr1 = D.first =new

LinkNode;

LinkNode

*destptr2 = E.first =new

LinkNode;

while(srcptr->link!=NULL&&srcptr->link->link!=NULL)

{

value =

srcptr->link->data;

destptr1->link

=

newLinkNode(value);

srcptr =

srcptr->link->link;

destptr1 =

destptr1->link;

}

destptr1->link

= NULL;

srcptr =

this->getHead();

srcptr =

srcptr->link;

while(srcptr->link!=NULL&&srcptr->link->link!=NULL)

{

value =

srcptr->link->data;

destptr2->link

=

newLinkNode(value);

srcptr =

srcptr->link->link;

destptr2 =

destptr2->link;

}

destptr1->link

= NULL;

}

#endif

节点头文件:LinkNode.h:

#ifndefLINKNODE_H

#defineLINKNODE_H

#include

template

structLinkNode

{

T data;

//数据域

LinkNode *link;

//指针域

LinkNode(LinkNode

*ptr= NULL){link = ptr;} //仅有指针域形参的构造函数

LinkNode(const

T&item,LinkNode

*ptr = NULL) //构造函数

{

data = item;

link = ptr;

}

};

#endif

主函数源文件:Main.cpp:

#include

#include"LinkedList.h"

#include"LinkNode.h"

void main()

{

LinkedListList1,List2,List3,List4,List5;

int a[] =

{1,2,3,4,5,6,7,8,9,10};

int b[] =

{1,2,3,4,5,6,7,8,9,10,11,12};

for (int i =

0;i<10;i++)

List1.Insert(i,b[i]);

for (int j =

0;j<12;j++)

List2.Insert(j,b[j]);

cout<

cout<

";

List1.Output();

cout<

";

List2.Output();

cout<

List3.Combine(List1,List2);

cout<

";

List3.Output();

cout<

List3.Turn();

cout<

";

List3.Output();

cout<

List3.Divide(List4,List5);

cout<

";

List4.Output();

cout<

";

List5.Output();

}

【实验过程】

设计好单链表的建立、拆分、合并、转置代码后,打开C++编译环境,建立两个空的头文件,分别输入节点类和链表类的声明代码及实现代码。然后新建主文件,对两个类的构造函数、复制构造函数以及合并,转置函数等进行调试,最后进行评估。

【实验体会】

转置算法为利用3个指针的经典算法,需要记牢。合并与拆分算法总体都是建立在复制函数算法的基础上。经过这次实验,对单链表的性质有了更深刻的体会。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值