我是靠谱客的博主 畅快蛋挞,最近开发中收集的这篇文章主要介绍单链表的创建与操作(有头节点),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.概念与特点

概念:        

        逻辑结构:线性结构 一对一

        存储结构:链式存储 内存中不一定是连续的

特点:

        在链表中 每个数据元素都是一个结点,以结构体的方式封装

        包含数据域和指针域

        数据域:用于存储数据元素的信息

        指针域:用于存储数据元素下一个结点的首地址

2.创建节点的结构体类型

typedef struct node{
int data;
//保存节点的数据(数据域)
struct node *next;
//保存下个节点的地址(指针域)
}link_list_t;

3.创建新节点的函数create_linklist()   

(1)定义一个结点类型的指针*L,并用malloc在堆空间分配内存;

(2)初始化结点数据,L->data=-1;L->next=NNULL;

(3)返回结点的首地址。

link_list_t *create_linklist(){
link_list_t *L=malloc(sizeof(link_list_t));//给结构体指针在堆内存上分配内存
if(NULL==L){
printf("创建链表失败n");
return NULL;
}
L->data=-1;
//初始化节点数据为-1
L->next=NULL;
//初始化节点next指向为空
return L;
}

4.创建头节点

 link_list_t *L=create_linklist();
//创建一个节点作为头节点

5.插入节点--头插法

int head_link(link_list_t *L,data_t value){//L单链表的头结点,value新节点的数据
if(NULL==L){
printf("参数有误n");
return -1;
}
link_list_t *N=create_linklist();
//创建一个新节点
N->data=value;
//初始化节点数据
N->next=L->next;
L->next=N;
return 0;
}

6.遍历单链表

(1)定义一个新的节点类型*q,初始化为q=L->next;

(2)循环条件q!=NULLL;

(3)循环体:q=q->next;

int show_link(link_list_t *L){
if(NULL==L){
printf("参数有误n");
return -1;
}
if(NULL==L->next){
printf("链表为空n");
return -1;
}
link_list_t *q=L->next;
//定义一个移动的节点类型的指针,用于遍历
while(q!=NULL){
//从首个有效的节点开始遍历
printf("%d ",q->data);
q=q->next;
}
puts("");
return 0;
}

7.任意位置删除节点

        思路:找到要删除位置的前一个节点。

        条件:pos大于等于0,且小于链表的长度

(1)定义一个动点*q=L;int i=0;

(2)循环q=q->next;直到定位到要删除节点的前一位;

(3)在循环时要判断p->next是否为空,如果为空则退出循环,表示pos位没有数据;

(4)当定位到要删除的前一个节点,定义另一个节点保存要删除节点的位置*p=q->next;

(5)令q->next=p->next;p->next=NULL;释放p指向的堆空间。

//删除时,要定位到要删除节点的前一个位置,以便删除
int pos_delete(link_list_t *L,int pos){
//pos位置信息
if(NULL==L){
printf("参数有误n");
return -1;
}
if(NULL==L->next){
printf("链表为空n");
return -1;
}
int i=0;
link_list_t *q=L;
for(i=0;i<pos;i++){
q=q->next;
if(q->next==NULL){
return -1;
}
}
link_list_t *p=q->next;
q->next=p->next;
free(p);
p=NULL;
return 0;
}

8.翻转单链表

链表翻转:

        现象:输出前---12345

        输出后---54321

        思路:将链表分为两个链表,从第一个有效数据后断开,前半部分为一个链表,后半部分 为 一个链表。对后半部分进行头删的同时将节点头插到前半部分,直到后半部分为空。

(1)定义一个节点类型的指针*q=L->next->next;

(2)拆分为两个链表分别为L和q,L->next->next=NULL;

(3)定义一个新的节点类型指针*p=NULL,指向要操作的节点;

(4)判断q是否为空,否的话令p=q;q=q->next;p->next=L->next;L->next=p;

(5)循环执行第4步,直到q==NULL。

//将单链表分为俩个单链表,分别进行头删和头插
int overturn_list(link_list_t *L){
if(NULL==L){
printf("参数有误n");
return -1;
}
if(NULL==L->next){
printf("链表为空n");
return -1;
}
link_list_t *p=L->next->next;
if(p==NULL){
printf("仅有一个元素n");
return -1;
}
L->next->next=NULL;
link_list_t *q=p;
while(q!=NULL){
p=q;
q=p->next;
p->next=L->next;
L->next=p;
}
return 0;
}

9.任意位置查找

data_t pos_find(link_list_t *L,int pos){
if(NULL == L || pos<0){
printf("输入参数有误n");
return -1;
}
if(NULL == L->next){
printf("表为空n");
return -1;
}
link_list_t *q=L;
int i=0;
for(;i<=pos;i++){
q=q->next;
if(NULL == q){
printf("输入的位置参数过大n");
return -1;
}
printf("%d位置的数据是%dn",pos,q->data);
return 0;
}
}

10.排序

        思路:只交换数据,不交换节点(冒泡排序)。

(1)定义两个移动的节点类型的指针q和p,一个用于交换数据的三方变量temp;

(2)判断L->next和L->next->next是否为空,成立的话,程序结束,表位空表或只有一个节点;

(3)上述不成立,则令q=L->next;

(4)令p=q->next;判断q->data是否大于p->data,成立,则交换数据;不成立,执行第5步;

(5)令p=p->next;判断p是否为空,不成立执行第4步;成立,执行第6步;

(6)令q=q->next;判断q是否为空,不成立,执行第4步,成立退出循环,程序结束。

//只交换数据
int sort_link(link_list_t *L){
if(NULL == L){
printf("输入参数有误n");
return -1;
}
if(NULL == L->next || NULL == L->next->next){
printf("表为空表或表中只有一个元素n");
return -1;
}
link_list_t *q=L->next;
link_list_t *p=NULL;
data_t temp=0;
while(NULL != q){
p=q->next;
while(NULL != p){
if(q->data>p->data){
temp = p->data;
p->data=q->data;
q->data=temp;
}
p=p->next;
}
q=q->next;
}
return 0;
}

最后

以上就是畅快蛋挞为你收集整理的单链表的创建与操作(有头节点)的全部内容,希望文章能够帮你解决单链表的创建与操作(有头节点)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部