单链表的插入和删除实验报告Word文件下载.docx
《单链表的插入和删除实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《单链表的插入和删除实验报告Word文件下载.docx(26页珍藏版)》请在冰豆网上搜索。
ListNode*LocateNode();
//函数,按值查找结点
voidDeleteList();
//函数,删除指定值的结点
voidprintlist();
//函数,打印链表中的所有值
voidDeleteAll();
//函数,删除所有结点,释放内存
//==========主函数==============
voidmain()
{
charch[10],num[10];
LinkListhead;
head=CreatListR1();
//用尾插入法建立单链表,返回头指针
printlist(head);
//遍历链表输出其值
printf("
Deletenode(y/n):
"
);
//输入“y”或“n”去选择是否删除结点
scanf("
%s"
num);
if(strcmp(num,"
y"
)==0||strcmp(num,"
Y"
)==0){
PleaseinputDelete_data:
scanf("
ch);
//输入要删除的字符串
DeleteList(head,ch);
printlist(head);
}
DeleteAll(head);
//删除所有结点,释放内存
}
//==========用尾插入法建立带头结点的单链表===========
LinkListCreatListR1(void)
charch[10];
LinkListhead=(LinkList)malloc(sizeof(ListNode));
//生成头结点
ListNode*s,*r,*pp;
r=head;
r->
next=NULL;
Input#toend"
//输入“#”代表输入结束
PleaseinputNode_data:
//输入各结点的字符串
while(strcmp(ch,"
#"
)!
=0){
pp=LocateNode(head,ch);
//按值查找结点,返回结点指针
if(pp==NULL){//没有重复的字符串,插入到链表中
s=(ListNode*)malloc(sizeof(ListNode));
strcpy(s->
data,ch);
r->
next=s;
r=s;
printf("
scanf("
returnhead;
//返回头指针
//==========按值查找结点,找到则返回该结点的位置,否则返回NULL==========
ListNode*LocateNode(LinkListhead,char*key)
ListNode*p=head->
next;
//从开始结点比较
while(p&
&
strcmp(p->
data,key)!
=0)//直到p为NULL或p->
data为key止
p=p->
//扫描下一个结点
returnp;
//若p=NULL则查找失败,否则p指向找到的值key的结点
//==========删除带头结点的单链表中的指定结点=======
voidDeleteList(LinkListhead,char*key)
ListNode*p,*r,*q=head;
p=LocateNode(head,key);
//按key值查找结点的
if(p==NULL){//若没有找到结点,退出
positionerror"
exit(0);
while(q->
next!
=p)//p为要删除的结点,q为p的前结点
q=q->
r=q->
q->
next=r->
free(r);
//释放结点
//===========打印链表=======
voidprintlist(LinkListhead)
//从开始结点打印
while(p){
%s,"
p->
data);
\n"
//==========删除所有结点,释放空间===========
voidDeleteAll(LinkListhead)
ListNode*p=head,*r;
while(p->
next){
r=p->
free(p);
p=r;
free(p);
运行结果:
加的添加结点的代码:
intInsert(ListNode*head)//theinsertfunction
ListNode*in,*p,*q;
intwh;
inputtheinsertnode:
in=(ListNode*)malloc(sizeof(ListNode));
in->
p=(ListNode*)malloc(sizeof(ListNode));
p->
q=(ListNode*)malloc(sizeof(ListNode));
q->
if(!
in)
return0;
in->
inputtheplacewhereyouwanttoinsertyoudata:
%d"
&
wh);
for(p=head;
wh>
0;
p=p->
next,wh--);
q=p->
p->
next=in;
in->
next=q;
return1;
最后提示为OK添加成功。
实验心得:
这个实验中主要修改的是ch和num把它们由指针改成数组因为不改的话在后面delect函数中会出现没有地址的情况找不到地址就不能执行功能然后把locate函数的判断语句改一下避免矛盾的出现。
实验二、二叉树操作
掌握二叉树的定义、性质及存储方式,各种遍历算法。
二、要求
采用二叉树链表作为存储结构,完成二叉树的建立,先序、中序和后序以及按层次遍历的操作,求所有叶子及结点总数的操作。
#defineMax20//结点的最大个数
typedefstructnode{
chardata;
structnode*lchild,*rchild;
}BinTNode;
//自定义二叉树的结点类型
typedefBinTNode*BinTree;
//定义二叉树的指针
intNodeNum,leaf;
//NodeNum为结点数,leaf为叶子数
//==========基于先序遍历算法创建二叉树==============
//=====要求输入先序序列,其中加入虚结点“#”以示空指针的位置==========
BinTreeCreatBinTree(void)
BinTreeT;
charch;
if((ch=getchar())=='
#'
)
return(NULL);
//读入#,返回空指针
else{
T=(BinTNode*)malloc(sizeof(BinTNode));
//生成结点
T->
data=ch;
T->
lchild=CreatBinTree();
//构造左子树
rchild=CreatBinTree();
//构造右子树
return(T);
//========NLR先序遍历=============
voidPreorder(BinTreeT)
if(T){
printf("
%c"
T->
//访问结点
Preorder(T->
lchild);
//先序遍历左子树
rchild);
//先序遍历右子树
//========LNR中序遍历===============
voidInorder(BinTreeT)
Inorder(T->
//中序遍历左子树
//中序遍历右子树
//==========LRN后序遍历============
voidPostorder(BinTreeT)
Postorder(T->
//后序遍历左子树
Postorder(T->
//后序遍历右子树
//=====采用后序遍历求二叉树的深度、结点数及叶子数的递归算法========
intTreeDepth(BinTreeT)
inthl,hr,max;
if(T){
hl=TreeDepth(T->
//求左深度
hr=TreeDepth(T->
//求右深度
max=hl>
hr?
hl:
hr;
//取左右深度的最大值
NodeNum=NodeNum+1;
//求结点数
if(hl==0&
hr==0)leaf=leaf+1;
//若左右深度为0,即为叶子。
return(max+1);
elsereturn(0);
//====利用“先进先出”(FIFO)队列,按层次遍历二叉树==========
voidLevelorder(BinTreeT)
intfront=0,rear=1;
BinTNode*cq[Max],*p;
//定义结点的指针数组cq
cq[1]=T;
//根入队
while(front!
=