问题描述:
什么是尾插法?
解析:
从一个空表开始,重复读入数据,生成新结点,将读入数据存放在新结点的数据域中,然后将新结点插入到当前链表的表尾上,直到读入结束标志为止。
具体算法实现
LinkList CreatListR(void)
{返回单链表的头指针
char ch
LinkList head头指针
ListNode *s,*r工作指启猜针
head=NULL链表开始为空
r=NULL尾指针初值为空
ch=getchar()读入第1个字符
while(ch!='\n'){
s=(ListNode *)malloc(sizeof(ListNode))生成新结点
s->data=ch将读入的数据放入新结点的数据域中
if (head!=NULL)
head=s新结点插入空表
else
r->next=s将新结点插巧旁纳到*r之后
r=s尾指针指向新表尾
ch=getchar()读入下一字符
}endwhile
if (r!=NULL)
r->next=NULL对于非空表,将尾结点指针域置空head=s
return head
}
注意:
⒈开始结点插入的特殊处理
由于开始结点的位置是存放在头指针(指针变量)中,而其余结点的位置是在其前趋结点的指针域中,插入开始结点时要将头指针指向开始结点。
⒉空表和非空表的不同处理
若读入的第一个字符就是结束标志符,则链表head是空表,尾指针r亦为空,结点*r不存在否则链表head非空,最后一个尾结点*r是终端结点,应将其指针域置空。
(3) 尾插法建带头结点的单链表
①头结点及作用
头结点是在链表的开始结点之前附加一个结点。它具有两个优点:
⒈由于开始结点的位置被存放在头结点的指针域中,所以在链表的第一个位置上的 *** 作就和在表的其它位置上 *** 作一致,无须进行特殊处理
⒉无论链表是否为空,其头指针都是指向头结点的非空指针(空表中头结点的指针域空),因此空表和非空表的处理也就统一了。
②带头结点的单链表
注意:
头结点数据域的阴影表示该部分不存储信息。在有的应用中可用于存放表长等附加信息。
③尾插法建带头结点链表算法
LinkList CreatListR1(void)
{用尾插法建立带头结点的单链表
char ch
LinkList head=(ListNode *)malloc(sizeof(ListNode))生成头结点
ListNode *s,*r工作指针
r=head尾指针初值也指向头结点
while((ch=getchar())!='\n'){
s=(ListNode *)malloc(sizeof(ListNode))生成新结点
s->data=ch将读入的数据放入新结点的数据域中
r->next=s
r=s
}
r->next=NULL终端结点的指针域置空,或空表的头结点指针域置空
return head
}
注意:
上述算法里,动态申请新结点空间时未加错误处理,这对申孝没请空间极少的程序而言不会出问题。但在实用程序里,尤其是对空间需求较大的程序,凡是涉及动态申请空间,一定要加入错误处理以防系统无空间可供分配。
//要先判断rear是否为空.//你的原程序中在插入数的时候,没设置head,所以head一直为null,则while循环p的值初始就为null,所以不会有任何输出。况且运行的话会出现运行时错误,因为rear的初值为null,i=1的时候,rear=null,这时候调用rear->next程序会报错退出,所以应该先判断rear是否为空,即判断表中是否有元素,没有元素的话,就应该将第一个插入的元素纳没设为rear,同时也要设为head。head=rear=p表宴茄腔示head = prear = p第晌衫二次插入的时候head仍然指向头元素,rear指向新元素。判断使用head和rear效果是一样的。
struct增加一个构造函数,for循环的逻辑改了一下
#include <iostream>
using namespace std
struct inode
{
inode(int i) : data(i), next(null) {}
int data
inode*next
}
int main()
{
int m=8, n = 4
inode *head = NULL, *rear = NULL
for(int i=1i<=ni++)
{
inode *p = new inode(i)
(rear == NULL ? head : rear->next) = p
rear=p
}
inode *p = head
while(p!=NULL)
{
cout<<p->data<<endl
p=p->next
}
return 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)