/****************************************************/ File name:no_head_link.c
Author:SimonKly Version:0.1 Date: 2017.5.20
Description:不带头节点的单链表
Funcion List:
*****************************************************/ #include <stdio.h>
#include <stdlib.h> typedef struct node
{
int id;
struct node * next;
}* Link, Node; /*创建链表*/
void create_link(Link * head)
{
*head = NULL;//空链表
} /*头插*/
void insert_node_head(Link * head, Link new_node)
{
new_node->next = *head;
*head = new_node;
} #if 1
/*尾插*/
void insert_node_tail(Link * head, Link new_node)
{
Link p = NULL; if (*head == NULL)
{
*head =new_node;
new_node->next = NULL;
return ;
}
else
{
p = *head;
while (p->next != NULL)
{
p = p->next;
}
p->next = new_node;
new_node->next = NULL;
}
}
#endif /*输出链表*/
void display_link(Link head)
{
Link p = NULL; p = head; if(p == NULL)
{
printf("link is empty!\n");
return ;
} while (p != NULL)
{
printf("id = %d\n", p->id);
p = p->next;
} putchar();
} /*检查malloc是否分配成功*/
void is_malloc_ok(Link new_node)
{
if (new_node == NULL)
{
printf("malloc error!\n");
exit(-);
}
} /*创建节点*/
void create_node(Link * new_node)
{
*new_node = (Link)malloc(sizeof(Node)); is_malloc_ok(*new_node);
} /*释放节点*/
void realse_node(Link * head)
{
Link p = NULL; p = *head;
while (*head != NULL)
{
*head = (*head)->next;//head移动
free(p);//释放head之前的节点
p = *head;
}
} /*中间插入节点*/
void insert_node_mid(Link * head, Link new_node, int loc)
{
int i;
Link p = NULL; p = *head; for(i = ; i < loc; i++)
{
p = p->next;
} new_node->next = p->next;
p->next = new_node;
} /*中间插入,前面*/
void insert_node_mid_front(Link * head, Link new_node)
{
Link p = NULL, q = NULL; p = q = *head; if (*head == NULL)
{
printf("link is empty\n");
return ;
} while (p != NULL && p->id != new_node->id)
{
q = p;
p = p->next;
} if (p == NULL)
{
printf("No such node in link!\n");
free(new_node);
return ;
}
if (p->id == (*head)->id)
{
new_node->next = *head;
*head = new_node;
}
else
{
q->next = new_node;
new_node->next = p;
}
}
#if 1
/*删除节点*/
void delete_node(Link * head, int data)
{
Link p = NULL, q = NULL; q = p = *head; if (p == NULL)//链表为空的时候
{
printf("link is empty!\n");
return ;
}
else//链表不为空的时候
{
while (p != NULL && p->id != data)//寻找节点
{
q = p;
p = p->next;
} if ((*head)->id == data)//删除节点为头节点时
{
*head = (*head)->next;
free(p);//free(q);
}
else//删除节点不为头节点,尾节点不用考虑
{
q->next = p->next;
free(p);
}
}
}
#endif #if 0
void delete_node(Link * head, int data)
{
Link p = NULL, q = NULL; q = p = *head; if (p == NULL)//链表为空的时候
{
printf("link is empty!\n");
return ;
}
else//链表不为空的时候
{
while (p != NULL && (p->next)->id != data)//寻找节点
{
p = p->next;
} if ((*head)->id == data)//删除节点为头节点时
{
*head = (*head)->next;
free(p);//free(q);
}
else//删除节点不为头节点,尾节点不用考虑
{
q = p->next;
p->next = q->next;
free(q);
}
}
}
#endif /*插入之后依旧有序*/
void insert_node_seq(Link * head, Link new_node)
{
Link p = NULL, q = NULL; p = q = *head; if (p == NULL)//链表为空的时候
{
*head = new_node;
new_node->next = NULL;
}
else
{
while (p != NULL && p->id < new_node->id)//寻找位置
{
q = p;
p = p->next;
} if ((*head)->id > new_node->id)//找到的节点为头节点
{
new_node->next = *head;
*head = new_node;
}
else
{
q->next = new_node;
new_node->next = p;
}
}
} #if 1
/*插入依旧有序实现方法二*/
void insert_node_seq_1(Link * head, Link new_node)
{
Link p = NULL;
Link q = NULL; p = q = *head; if (p == NULL)//空链表
{
*head = new_node;
new_node->next =NULL;
}
else
{
while ((p->id < new_node->id) && (p->next != NULL))
{
q = p;
p = p->next;
} if ((*head)->next == NULL)//一个节点的时候
{
if (p->id > new_node->id)
{
new_node->next = *head;
*head = new_node;
}
else
{
p->next = new_node;
}
}
else
{
if (p->next == NULL)//尾节点
{
if (p->id > new_node->id)//插入前
{
q->next = new_node;
new_node->next = p;
}
else
{
p->next = new_node;
}
}
else//不是尾节点
{
if((*head)->id > new_node->id)//头节点
{
new_node->next = *head;
*head = new_node;
}
else//中间插入时
{
q->next = new_node;
new_node->next = p;
}
}
}/*end of if()*/
}/*end of if (p == NULL)*/
}
#endif int main()
{
Link head = NULL;//防止出现野指针
Link new_node = NULL;//防止出现野指针
int i;
int data; create_link(&head);//创建链表 for (i = ; i < ; i++)//值域赋值,并插入新节点
{
// new_node = (Link)malloc(sizeof(Node));//创建新节点
create_node(&new_node);
// new_node->id = i + 1;//赋值
// insert_node_head(&head, new_node);//插入节点,头插
// insert_node_tail(&head, new_node);//插入节点,尾插 printf("please input node value:\n");
scanf("%d", &new_node->id);
insert_node_seq(&head, new_node);
// insert_node_seq_1(&head, new_node);
display_link(head);//输出节点的值域
} display_link(head);//输出节点的值域 #if 0
create_node(&new_node);
new_node->id = i + ;
insert_node_mid(&head, new_node, );//指定位置插入,中间插入
putchar();
display_link(head);//输出节点的值域 #if 0
create_node(&new_node);
scanf("%d", &new_node->id);
insert_node_mid_front(&head, new_node);
display_link(head);//输出节点的值域
#endif scanf("%d", &i);
delete_node(&head, i);//删除指定节点
display_link(head); #if 0 create_node(&new_node);
scanf("%d", &new_node->id);
insert_node_seq(&head, new_node);//有序插入指定元素
display_link(head);
#endif
#endif
realse_node(&head);//释放节点 display_link(head);//输出节点的值域
return ;
}

由于链式数据结构中有指针的各种指向问题,所以在纸上画图是比较容易理解。

其中在对头指针(注意是头指针,不是头节点,两个不是一个概念,头指针是整个链表的操作的基础,链表存在的象征,头指针是整个“链表公司”的一把手,头头结点是链表中的第一个元素)的操作,除了在插入,删除和销毁中头指针的指向发生改变,需要直接对头指针head操作外,其他方法都不要对头指针进行操作,以免丢失整个链表。

在对链表中的增加时,需要考虑链表中开始存在的元老级的“人物”,所以我们不能随便就对它们变换“岗位”,我得先找到”接班人“之后再对这些元老级的岗位进行调整。

在对链表中的节点进行删除时,也需要首先考虑这些元老级的“人物”,毕竟人家没有功劳也有苦劳,我们得代理好它走后它的”上级“和他的”下级“沟通交流的问题。

代码中的一些条件编译和注释是未完成一些功能的另一种方法。

在销毁整个链表时,相当于整个链表公司破产,作为公司一把手的head,依次需要对手下任劳任怨的员工进行思想工作。当整个公司没有员工时,一把手也什么都没有了即NULL。

代码中的功能函数包括:

1.创建链表

2.创建节点

3.插入节点------------头插,尾插以及插入即有序,指定位置插入的方法,根据需要选择合适的方法

  头插:实现链式栈

  尾插:实现链式队列

4.删除节点

5.销毁整个链

6.判断malloc函数是否执行成功

7.输出链

不带头结点的单链表------C语言实现的更多相关文章

  1. c语言实现--不带头结点的单链表操作

    1,不带头结点的单链表操作中,除了InitList(),GetElem(),ListInsert(),ListDelete()操作与带头结点的单链表有差别外,其它的操作基本上一样. 2,不带头结点单链 ...

  2. java编写带头结点的单链表

    最近在牛客网上练习在线编程,希望自己坚持下去,每天都坚持下去练习,给自己一个沉淀,不多说了 我遇到了一个用java实现单链表的题目,就自己在做题中将单链表完善了一下,希望大家作为参考也熟悉一下,自己 ...

  3. C/C++中创建(带头结点、不带头结点的)单链表

    1.带头结点的单链表(推荐使用带头结点的单链表)(采用尾插法) 了解单链表中节点的构成 从上图可知,节点包含数据域和指针域,因此,在对节点进行定义时,我们可以如下简单形式地定义: /* 定义链表 */ ...

  4. 链表习题(2)-一个集合用带头结点的单链表L表示,编写算法删除其值最大的结点。

    /*一个集合用带头结点的单链表L表示,编写算法删除其值最大的结点.*/ /* 算法思想:使用pre,p,premax,max四个指针,pre和p进行比较,premax和max进行最后的删除操作 通过遍 ...

  5. 链表习题(1)-设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点

    /*设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点*/ /* 算法思想:设f(L,x)的功能是删除以L为首结点指针的单链表中所有值等于x的结点, 则显然有f(L->next,x)的 ...

  6. 有一个线性表,采用带头结点的单链表L来存储,设计一个算法将其逆置,且不能建立新节点,只能通过表中已有的节点的重新组合来完成。

    有一个线性表,采用带头结点的单链表L来存储,设计一个算法将其逆置,且不能建立新节点,只能通过表中已有的节点的重新组合来完成. 分析:线性表中关于逆序的问题,就是用建立链表的头插法.而本题要求不能建立新 ...

  7. 不带头结点的单链表(基于c语言)

    本篇文章的代码大多使用无头结点的单链表: 相关定义: #include <stdio.h> #include <stdlib.h> #include <assert.h& ...

  8. 带头节点的单链表-------C语言实现

    /***************************************************** Author:Simon_Kly Version:0.1 Date:20170520 De ...

  9. Python实现不带头结点的单链表

    1 # 创建一个节点类 2 class Node: 3 def __init__(self, item): 4 self.item = item 5 self.next = None 6 7 8 # ...

随机推荐

  1. SQL必知必会——插入数据(十五)

    1.数据插入 INSERT用来将行插入(或添加)到数据库表.插入有几种方式: 插入完整的行插入行的一些部分插入某些查询的结果注意:1.使用INSERT语句可能需要客户端/服务端DBMS中的特定安全权限 ...

  2. 【Shiro】五、Apache Shiro加密

    Shiro提供了更好封装,更好使用的加密算法API,可以作为平时使用的一个工具类的预选方案. Shiro的密码学 基本特性 接口驱动,基于POJO 对JCE(Java Cryptography Ext ...

  3. 使用密码登陆Amazon EC2

    用的是亚马逊推荐的系统:Amazon Linux AMI 2015.09.1 (HVM) 创建instance后,会有一个pem的key使用该密钥登陆到服务器上后,默认用户名为 ec2-user 直接 ...

  4. Linux基础-命令概述

    概述 很多人可能在电视或电影中看到过类似的场景,黑客面对一个黑色的屏幕,上面飘着密密麻麻的字符,梆梆一顿敲,就完成了窃取资料的任务,是不是很帅!我们作为一个开发者, 即使不为了成为上述的人, 也需要会 ...

  5. vue input框type=number 保留两位小数自定义组件

    第一步:自定义组件MyNumberInput.vue<template> <input class="numberInput" type="number ...

  6. CentOS 7 64位虚拟机安装过程

    第一步:新建一个虚拟机,选择典型安装,点击下一步.

  7. java 并发——CountDownLatch

    java 并发--CountDownLatch 简介 public class CountDownLatch { private final Sync sync; private static fin ...

  8. Java构造函数(构造器)

    构造函数是用于在对象创建后立即初始化对象的代码块.构造函数的结构看起来类似于一个方法. 声明构造函数 构造函数声明的一般语法是: 1 2 3 <Modifiers> <Constru ...

  9. mysqldump备份和恢复

    一.备份单个数据库 1.备份命令:mysqldump MySQL数据库自带的一个很好用的备份命令.是逻辑备份,导出 的是SQL语句.也就是把数据从MySQL库中以逻辑的SQL语句的形式直接输出或生成备 ...

  10. Promise篇

    Promise 原理解析与实现(遵循Promise/A+规范)   1 什么是Promise? Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解 ...