插入链表具体思路及其算法
1,查找要插入值的具体位置即需要找插入值的前驱
struct node *head,*p,*q,*s; p=head; s->data=elem; while(p!=NULL&&p->data < elem) { q=p;//q始终停留在P的前面 也就是q是要插入值的前驱 q=q->next; }
2,分情况讨论
{
1、遍历完q循环结束也并非找到比elem更大的数据{a、链表为空链表 b、elem就是最大值 插入尾部即可}
2、 找到了比elem更大的值{c、elem是整个链表中最小的值 插入头部做头结点 d、非空链表中elem就是最大值 插入尾部 q->next=s e、找到了比elelm更大的值}
if(p==NULL)//循环结束了 没找到比elem更大的节点 { //分情况:链表为空链表 if(head=NULL) { s->next=NULL;//考虑插入值得前后 head=s; } //2、elem就是整个链表中的最大值 else { q->next=s; s-s->next=NULL; } } //在循环的过程中找的了p //分情况:要插入的值是最小值 插入的字位于尾结点和头结点之间 else{ if(p==head) { s->next=head; head=s; } else { q->next=s; s->next=p; } }
3、常规创建遍历链表释放资源
例题
/****/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node//创建节点数据库
{
int data;//包括数据域
struct node *next;//指向下一个节点的指针域
};
struct node * insertlinkby_elem(struct node *head, int elem);
void destroy(struct node* head);//释放资源
struct node* creatlink();//创建节点链表
void traverse(struct node* head);//遍历节点
int main()
{ int c;
struct node *head;
head=creatlink(); //用尾插法创建链表
scanf("%d",&c);
head=insertlinkby_elem(head,c);
traverse(head);
destroy(head);
}
struct node * insertlinkby_elem(struct node *head, int elem)
{
//在单链表head中插入值为elem的结点
struct node *p=head,*q,*s;
s=(struct node* )malloc(sizeof(struct node));
// @#1 //申请结点
s->data=elem;
//查找
//如果p所指向的结点存在,并且数据小于elem ,指针往后移动
//直到结束(没有找到数据)或者找到第一个大于elem为止
while(p!=NULL&&p->data < elem)
{
q=p; //q指针停在p前面的结点
p=p->next; //更新p值是为了寻找elem的前驱
}
// 分情况处理
if(p==NULL) //没找到比elem大的数据
{
if(head==NULL) //空链表
{
s->next=NULL; //头指针指向第二个结点
head=s;
}
else //链表 //处理链接关系
// 非空,elem是最大元素,放入最有一个i额结点
{
//@@1
q->next = s;
s->next=NULL;
//@@1
}
}
else //找到结点
{
if(p==head ) //第一个结点,最小值
{
//@@2
s->next=head;
head=s;
//处理链接关系
//@@2
}
else //找到了结点为第一个以外的结点
{
q->next=s;
s->next=p;
}
}
return head;
}
struct node* creatlink()
{ struct node* head=NULL;
int c;
struct node *p,*q;
while(1)
{ scanf("%d",&c);
if(c==-1) break;
//申请结点空间
p = (struct node *) malloc (sizeof(struct node));
//初始化结点数据域
p->next = NULL;
p->data = c;
if(head == NULL)
{
head = p;
q=p; //设置尾指针
}
else
{
q->next = p; //挂入链尾
q=p; //设置尾指针
}
}
return head;
}
void traverse(struct node* head)
{ struct node *p=head;
while( p!=NULL) //如果p指向的结点不是空结点
{
printf("%d ",p->data); //则输出所指向的结点的数据域
p=p->next; //让p指向下一个结点
}
}
void destroy(struct node* head)
{ struct node *p;
while(head!=NULL)
{
p = head; //p指向要销毁的结点
head = head ->next; //head指向再下一个要销毁的结点
free(p); //销毁p指向的结点
}
}
题目描述
原由链表结点的数据是按照从小到大排序的,输入一个新的数据,插入到链表中,使它仍然有序
输入
第一行输入一组正整数(除-1外, 其他以从小到大的序列给出)-1结束,创建链表
第二行输入要插入的整数
输出
插入后有序的序列
样例输入
1 3 4 5 7 9 -1 6
样例输出
1 3 4 5 6 7 9