单链表的几类操作介绍(头结点没有数据)
来源:互联网 发布:戴勒姆波特知乎 编辑:程序博客网 时间:2024/06/05 09:41
1.定义一个单链表的结构体
typedef struct _Node
{
int data;
struct node1 *next;
}node;
2.创建一个链表,通过从键盘输入数值,当输入数值为0时跳出循环,这里是以0结束,实际上可以通过程序编写,随便用其他的方式跳出输入模式,而形成一个链表。在这个被创建的链表中头结点是没有数据的。
node *creatnode()
{
int i=0,n;
node *head,*p,*q;
head=(node*)malloc(sizeof(node));
if(head==NULL)
return NULL;
while(1)
{
printf("please input a data,put 0 over\n");
scanf("%d",&n);
if(n==0)
break;
p=(node*)malloc(sizeof(node));
p->data=n;
if(++i==1)
head->next=p;
else
q->next=p;
q=p;
}
q->next=NULL;
return head;
}
3.获取链表的长度
由于头结点没有数据,所以循环从头结点->next开始遍历,直到遇到NULL为止。最后返回链表的长度
int length(node *p)
{
int len=0;
while(p->next!=NULL)
{
len++;
p=p->next;
}
return len;
}
4.打印链表中存储的数据
这个其实和获取链表的长度一样的道理,都是需要遍历链表,但是在遍历前需要判断链表是否为空,若为空,立即返回,不为空开始遍历,直到遇到NULL为止。
void printnode(node *p)
{
node *q;
if(p->next==NULL)
{
printf("the node is empty:\n");
return;
}
else
{
q=p->next;
while(q!=NULL)
{
printf("%d\t",q->data);
q=q->next;
}
}
printf("\n");
}
5.链表的定位
链表的定位返回值分两种,一种可以返回定位到某个节点的数据,另一种是返回以此节点的地址
两个函数传入的参数都是一样,一个参数是需要操作的链表,另一个参数是节点在链表中的位置
第二个参数不能小于等于0,等于0其实就是头节点,这样的操作意义不大,同时也不能超过链表
本身的长度,所以在这个函数中调用了前面测量链表长度的函数。
int search_node(node *head,int pos)
{
if(pos<0)
{
printf("the pos can not smaller than 0\n");
return -1;
}
else if(pos==0)
{
printf("the position is the head\n");
return -1;
}
else if(head==NULL)
{
printf("the node is empty\n");
return -1;
}
else if(pos>length(head))
{
printf("the pos over the length of the node\n");
return -1;
}
else
{
while(pos--)
{
head=head->next;//往后遍历一次pos就要减一
}
}
return head->data;
}
node *search_node1(node *head,int pos)
{
if(pos<0)
{
printf("the pos can not smaller than 0\n");
return NULL;
}
else if(pos==0)
{
printf("the position is the head\n");
return NULL;
}
else if(head==NULL)
{
printf("the node is empty\n");
return NULL;
}
else if(pos>length(head))
{
printf("the pos over the length of the node\n");
return NULL;
}
else
{
while(pos--)
{
head=head->next;
}
}
return head;
}
6.删除链表中的节点
在进行删除操作前需要先判断需要删除的位置在哪里,若位置不合适,直接返回
if(pos<=0||(pos>length(head)))
{
printf("the position is wrong\n");
return NULL;
}
如果链表只有头结点也,直接返回
if(head->next==NULL)
{
printf("the node is empty\n");
return NULL;
}
如果以上均不满足,则可以开始删除节点,根据前面的定位函数,可以定位到需要被删除的节点的前一个节点pre
假设需要被删除的节点为cur,它的下一个节点next就是cur->next;要把cur删掉,只需让pre->next=next即可
当然在进行这一步操作前需要判断定位到被删除节点的前一个节点pre是不是为空,且下一个节点是不是为NULL.
node *delete_node(node *head,int pos)
{
node *item=NULL;
if(pos<=0||(pos>length(head)))
{
printf("the position is wrong\n");
return NULL;
}
if(head->next==NULL)
{
printf("the node is empty\n");
return NULL;
}
head=search_node1(head,pos-1);
if(head!=NULL&&head->next!=NULL)
{
item=head->next;
head->next=item->next;
item=NULL;
}
return head;
}
7.插入节点
链表插入节点原理和删除节点基本类似,可以参考删除节点的过程来理解
node *insert_node(node *head,int pos,int data)
{
node *item=NULL;
node *p=head;
if(pos<=0||(pos>length(head)))
{
printf("the position is wrong\n");
return NULL;
}
if(head->next==NULL)
{
printf("the node is empty\n");
return NULL;
}
item=(node*)malloc(sizeof(node));
item->data=data;
head=search_node1(head,pos);
if(head!=NULL&&head->next!=NULL)
{
item->next=head->next;
head->next=item;
}
return p;
}
完整程序如下:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct node1
{
int data;
struct node1 *next;
}node;
node *creatnode()
{
int i=0,n;
node *head,*p,*q;
head=(node*)malloc(sizeof(node));
if(head==NULL)
return NULL;
while(1)
{
printf("please input a data,put 0 over\n");
scanf("%d",&n);
if(n==0)
break;
p=(node*)malloc(sizeof(node));
p->data=n;
if(++i==1)
head->next=p;
else
q->next=p;
q=p;
}
q->next=NULL;
return head;
}
int length(node *p)
{
int len=0;
while(p->next!=NULL)
{
len++;
p=p->next;
}
return len;
}
void printnode(node *p)
{
node *q;
if(p->next==NULL)
{
printf("the node is empty:\n");
return;
}
else
{
q=p->next;
while(q!=NULL)
{
printf("%d\t",q->data);
q=q->next;
}
}
printf("\n");
}
int search_node(node *head,int pos)
{
if(pos<0)
{
printf("the pos can not smaller than 0\n");
return -1;
}
else if(pos==0)
{
printf("the position is the head\n");
return -1;
}
else if(head==NULL)
{
printf("the node is empty\n");
return -1;
}
else if(pos>length(head))
{
printf("the pos over the length of the node\n");
return -1;
}
else
{
while(pos--)
{
head=head->next;
}
}
return head->data;
}
node *search_node1(node *head,int pos)
{
if(pos<0)
{
printf("the pos can not smaller than 0\n");
return NULL;
}
else if(pos==0)
{
printf("the position is the head\n");
return NULL;
}
else if(head==NULL)
{
printf("the node is empty\n");
return NULL;
}
else if(pos>length(head))
{
printf("the pos over the length of the node\n");
return NULL;
}
else
{
while(pos--)
{
head=head->next;
}
}
return head;
}
node *delete_node(node *head,int pos)
{
node *item=NULL;
if(pos<=0||(pos>length(head)))
{
printf("the position is wrong\n");
return NULL;
}
if(head->next==NULL)
{
printf("the node is empty\n");
return NULL;
}
head=search_node1(head,pos-1);
if(head!=NULL&&head->next!=NULL)
{
item=head->next;
head->next=item->next;
item=NULL;
}
return head;
}
node *insert_node(node *head,int pos,int data)
{
node *item=NULL;
node *p=head;
if(pos<=0||(pos>length(head)))
{
printf("the position is wrong\n");
return NULL;
}
if(head->next==NULL)
{
printf("the node is empty\n");
return NULL;
}
item=(node*)malloc(sizeof(node));
item->data=data;
head=search_node1(head,pos);
if(head!=NULL&&head->next!=NULL)
{
item->next=head->next;
head->next=item;
}
return p;
}
int main()
{
int len=0;
node *head,*head1,*head2;
printf("please input some date and creat a node\n");
head=creatnode();
printnode(head);
len=length(head);
printf("the length of the node is:%d\n",len);
len=search_node(head,3);
printf("the data of the pos is %d\n",len);
delete_node(head,3);
printf("after delete: the node is :\n");
printnode(head);
printf("now ready to insert a number:\n");
printf("please input a data:\n");
scanf("%d",&len);
head=insert_node(head,3,len);
printf("after insert: the node is :\n");
printnode(head);
return 0;
}
- 单链表的几类操作介绍(头结点没有数据)
- (学习java)没有头结点的单链表
- 没有头结点的单链表如何删除结点
- 删除没有头结点的链表指点节点操作
- 带有头结点的单链表的操作
- 单链表的基本操作(头结点)
- 没有头结点的单链表[c语言实现]
- 带有头结点的循环单链表的相关操作
- 实现有头结点的单链表的简单操作
- bo2-3.c 带有头结点单链表的基本操作
- 实现无头结点单链表的基本操作函数
- 单链表的头结点和结点
- 带有头结点的链表与没有头结点的链表的对比
- 单链表的头结点和头指针
- 关于有头结点和无头结点的单链表
- 单链表操作_头结点方式
- 单链表的建立(头部延长、尾部延长)、插入操作、删除操作(无头结点的删除、有头结点的删除)
- 设一个没有头结点指针的单链表。一个指针指向此单链表中间的一个结点(不是第一个,也不是最后一个结点),将该结点从单链表中删除,要求时间复杂度O(1)。
- Java Calendar一般用法
- 设计模式原则备忘
- 文章标题
- struct中包含vector<int>时,push_back的时候出现内存错误
- 关于hashCode
- 单链表的几类操作介绍(头结点没有数据)
- 百度搜索
- 入门专题-docker
- 让logstash每次读取文件都从头开始读取的办法
- 【PAT】【Advanced Level】1082. Read Number in Chinese (25)
- CNTK API文档翻译(18)——多对多神经网络处理文本数据(2)
- 炸弹人
- HDU2717 Catch That Cow
- 带你玩转超级列表框 5 保存内容读取与选择性保存