问题出在:s create_list()这个函数
我们来分析下:
p=(s )malloc(sizeof(s));//申请一个新的空间
p->i=a[j];//为该空间的数据单元赋值
j--;//循环条件变量
p->next=h->next;//意味着p的下一个空间与头指针h一致
h->next=p;//h的下一个元素为p这个新空间
好了,现在我们分析最后这两句:(倒数第二句我们称为句A,最后一句称句B)
1、h为定址:h指针指向的空间始终不变这个比较好理解,因为AB句对h的 *** 作只 *** 作它的next。那好,现在我们令h的地址为0x00
2、如图:看看程序运行的流程。
所以另一种改法是:去掉p->next = '\0‘就可以了,不然的话,就前功尽弃了。当然,最后还是要加上free(p)
此时输出的是:12345
改后的程序如下:
s create_list()
{
int a[]={1,2,3,4,5},j=4;
s h,p;
h=(s )malloc(sizeof(s));
h->next='\0';
while(j>=0)
{
p=(s )malloc(sizeof(s));
p->i=a[j];j--;p->next=h->next;h->next=p;
}
/p->next='\0';/
free(p);
return h;
}
<<<<<最后,十分感谢你,让我琢磨出了双指针建单链表的方法。我第一次给你的方法要用三指针
#include<stdlibh>
#include "nodedefh"
#define CreateLinklistWay 1 // 0表示头插法创建链表,1表示尾插法创建链表
#if !CreateLinklistWay
/
函数名称:linklist CreateLinklistHead()
函数功能:利用头插法创建链表
参 数:无
返 回 值:创建完链表后的链表头结点
说 明:无
/
extern linklist CreateLinklistHead()
{
int x, i, nodeNum;
linklist head, temp; // 头结点与临时结点
head = (linklist )malloc(sizeof(linklist)); // 生成表头结点
head->next = NULL; // 给表头结点的指针域赋值
printf("请输入链表中结点的个数:");
scanf("%d", &nodeNum);
for(i=1; i<=nodeNum; i++)
{
printf("请输入第 %d 个结点的数据:", i);
scanf("%d", &x);
temp = (linklist )malloc(sizeof(linklist)); // 生成新的结点
temp->data = x; // 对新结点的数据域赋值
// 将新结点插到头结点之后
temp->next = head->next;
head->next = temp;
}
return head; // 返回新建链表的头结点
}
#else
/
函数名称:linklist CreateLinklistRear()
函数功能:利用尾插法创建链表
参 数:无
返 回 值:创建完链表后的链表头结点
说 明:无
/
extern linklist CreateLinklistRear()
{
int x, i, nodeNum;
linklist head, rear, temp; // 定义头结点、尾结点和临时结点
head = (linklist )malloc(sizeof(linklist)); // 生成表头结点,表头结点不存放数据
head->next = NULL; // 将表头结点的指针域赋值为NULL
rear = head; // 将表头结点赋值给表尾结点
printf("请输入链表中结点的个数:");
scanf("%d", &nodeNum);
for(i=1; i<=nodeNum; i++)
{
printf("请输入第 %d 个结点的数据:", i);
scanf("%d", &x);
temp = (linklist )malloc(sizeof(linklist)); // 生成新的结点
temp->data = x; // 新增结点的数据域
temp->next = NULL; // 新增结点的指针域(由于是尾插法,所以插入的结点都在尾部,即指针域为NULL)
rear->next = temp; // 使前一个结点指向新增结点(head->next=temp)
rear = temp; // 将新增结点赋值给尾结点(尾插法,插入的结点在尾部)(rear=head->next)
}
//rear->next = NULL; // 将尾结点的指针域赋值为空(为了方便检验链表是否为空链表)
return head; // 返回头结点
}
#endif
这是个很简单的链表创建和输出
#include<stdioh>
#include<stdlibh>
typedef struct linkednode
{
char data;
struct linkednode next;
}node,link_list;//链表节点的结构及重命名
link_list creat()//创建一个链表返回类型是链表的首地址
{
link_list L;
node p1,p2;
char data;
L=(node)malloc(sizeof(node));//开辟存储空间
p2=L;
while((data=getchar())!='\n')//输入回车键时结束输入
{
p1=(node)malloc(sizeof(node));
p1->data=data;
p2->next=p1;
p2=p1;
}
p2->next=NULL;
return L;
}
void print(link_list L)//把链表输出
{
node p;
p=L->next;
while(p!=NULL)
{
printf("%c",p->data);
p=p->next;
}
printf("\n");
}
void main()
{
link_list L=NULL;
char x;
printf("请输入链表节点:\n");
L=creat();
print(L);
}
造成这个的原因是:链表的节点是char类型,而输入中的回车也是字符,因此会记录到输入的缓冲区中,造成程序把回车也记录为链表的节点。
解决的方法有2个:
(1)在scanf中添加忽略的参数设置,即将
scanf("%c",&(s->data) );改为
scanf("%c%c",&(s->data) );(2)在输入字符后,清空缓冲区,即在所有scanf函数后面,添加函数
fflush(stdin);//单链表的建立:
LinkList CreateList(void)
{
int i,n=5; /n因题型而定大小/
ListNode head,p,q;//遍历链表一般会用到这三个指针,头指针和指前后两个节点的一对指针,这对指针遍历中移动
head=(ListNode)malloc(sizeof(ListNode));//为头结点申请空间
p=head;//p指向头结点
printf("\n请输入%d整数建立链表:",n);
for(i=1;i<n;i++)
{scanf("%d",&(p->data));//从头读入节点数据,第一遍的时候p指head,就把数据读入了HEAD中的data这个变量里
q=(ListNode)malloc(sizeof(ListNode)); //q指新节点 为新的节点申请空间
p->next=q;//把q连接到P后
p=q;} //p移动到q的位置,就是说p往后挪了一个,指向新的节点。在做循环里读入的 *** 作时,就是对新节点的 *** 作
scanf("%d",&(p->data));//到尾节点时就不再向后移了,读入尾节点信息
p->next=NULL;//尾节点的后继为空
return(head);//返回所建列表头指针的位置
}
//单链表的打印
void PrintList(LinkList head)
{
ListNode p;//建遍历用的指针 不要直接用头指针移动
printf("\n当前单链表的具体数据为:");
p=head;//从头开始
while(p!=NULL)//p=null时到尾部 跳出循环
{
printf("%d ",p->data);//打印节点内容
p=p->next;//向后移一个位置
}
printf("\n");
}
# include <iostreamh> struct node {
char data;
node next;
};
node create();
void showList(node head);
int main()
{
node head;
head=create();
showList(head);
return 0; } node create()
{ node head=NULL;
node pEnd=head;
node pS;
char temp;
cout<<"Please input a string end with'#':"<<endl;
do
{ cin>>temp;
if(temp!='#'){
pS=new node;
pS->data=temp;
pS->next=NULL;
if(head==NULL){
head=pS;}
else{
pEnd->next=pS;
}
pEnd=pS;
}
}while(temp!='#');
return head;
}
void showList(node head){
node pRead=head ;
cout<<"The data of link list are: "<<endl;
while(pRead!=NULL)
{ cout<<pRead->data;
pRead=pRead->next;
}
cout<<endl;
}
判断k<i
这个可以放在前面,也是用来判断输入参数是否正确,链表开始应该是1,如果i<1那就不对了。
因为删除节点是一个一个删除的,而c语言里面删除是用free。当删除的时候。指向下一个节点的指针也没了。
所以用u指向当前要删除的节点,p指向下一个节点。
然后释放当前节点。
编程思路:从头到尾读出该链表数据并存入数组中,然后倒序输出数组元素
源代码:
void dao_visit(Link l)
{
Link rcv=l;
Link rcv2=rcv;
int a;
int lenth=0;
int i=0;
//获得单链表长度
while(rcv)
{
lenth++;
rcv=rcv->next;
}
//为指针a分配lenth个空间
a=(int )malloc(lenthsizeof(int));
//将单链表的数据写入a中
while(rcv2)
{
a[i]=rcv2->data;
rcv2=rcv2->next;
i++;
}
//倒序输出
for(i=0;i<lenth;i++)
printf("%d\n",a[lenth-1-i]);
free(a);
}
以上就是关于创建单链表的C程序全部的内容,包括:创建单链表的C程序、求一份实现单链表的基本 *** 作的c语言程序,包括输入元素,谢谢。、用C语言实现建立一个单链表的过程,并实现打印链表中每一个元素,写出完整程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)