一、指针与单链表

    1、定义:通过使用指针将节点(结点)链接起来成为链表

    2、节点(结点):

      1)、数据域:主要用来存储数据,可以基本数据类型,也可以是构造数据类型;

      2)、指针域:主要用来当前节点(结点)的下一个节点的地址;

      3)、使用命名结构体嵌套定义;

      4)、定义结构体

      5)、定义结构体指针

  定义节点数据的代码如下:

  #define DataType int

  typedef struct _node{
DataType data;
struct _node *next;
} Node;

  其中第3行代码使用宏定义的方式定义数据类型,也可以使用类型定义数据类型:

  typedef  int  DataType;

  typedef struct _node{
DataType data;
struct _node *next;
} Node;

  代码作用是一样一样的。

    3、链表:

      1)、将一系列节点通过特定的方式链接足层的数据结构;

      2)、链表中通常会有一个头节点

      3)、链表中通常会有一个尾节点

      4)、链表中通常会有一个当前节点;

 typedef struct _list{
Node *head;
Node *tail;
Node *current;
} List;

  链表的定义需要Node节点定义的支持,若不单独定义也可以直接使用节点指针即可。

      5)、常见的节点操作;节点操作是根据需要自己把握的事情,通常是完成结构数据的初始化等工作。

      6)、对指针使用sizeof运算获取指针长度

    4、链表中常见操作:

      1)、链表初始化initialList;

      2)、链表的头插法addHead;

      3)、链表的尾插法addTail;

      4)、链表中获取指定数据节点的指针getNode;

      5)、链表中删除节点deleteNode;

      6)、链表中获取表的长度getLength;

      7)、输出链表中的所有数据displayList;

  根据以上数据类型的需要和链表中需要的操作可以抽象出链表的抽象数据类型,使用list.h表示:

  #ifndef list_h
#define list_h
typedef int DataType; typedef struct _node{
DataType data;
struct _node *next;
} Node; typedef struct _list{
Node *head;
Node *tail;
Node *current;
} List; void initList(List *);
void addHead(List *, DataType);
void addTail(List *, DataType);
Node *getNode(List *, DataType);
void deleNode(List *, DataType);
int getLength(List *);
void dispList(List *); #endif

  操作实现的代码如下:

   #include <stdlib.h>
#include <stdio.h> #include "list.h" //链表初始化
void initList(List *list){
list->head = NULL;
list->tail = NULL;
list->current = NULL;
} //链表头插法
void addHead(List *list, DataType iData){
Node *node = (Node *)malloc(sizeof(Node));
node->data = iData;
node->next = NULL; if(list->head == NULL){
list->tail = node;
}else{
node->next = list->head;
}
list->head = node; return;
} //链表尾插法
void addTail(List *list, DataType iData){
Node *node = (Node *)malloc(sizeof(Node));
node->data = iData;
node->next = NULL; if(list->head == NULL){
list->head = node;
}else{
list->tail->next = node;
}
list->tail = node; return; } //链表节点获取
Node *getNode(List *list, DataType iData){
Node *node = (Node *)malloc(sizeof(Node));
node = list->head;
while(node != NULL){
if(node->data == iData){
return node;
}else{
node = node->next;
}
} return NULL;
} //删除链表中的节点
void deleNode(List *list, DataType iData){
if(list->head->data == iData){
list->head = list->head->next;
}
Node *prev = list->head;
Node *node = prev->next;
while(node != NULL){
if(node->data == iData){
prev->next = prev->next->next; return;
}else{
prev = prev->next;
node = node->next;
}
} return;
} //链表长度
int getLength(List *list){
Node *node = list->head;
int i = ;
while(node != NULL){
node = node->next;
i++;
} return i;
} //链表输出
void dispList(List *list){
Node *node = list->head;
int i = ;
while(node != NULL){
printf("the %dth node: %d\n", i + , node->data);
node = node->next;
i++;
}
printf("disp finished!\n"); return;
}

  测试代码如下:

    #include "list.h"
#include <stdlib.h> int main(int argc, char **argv)
{
List *list1 = (List *)malloc(sizeof(List));
printf("the first:\n");
initList(list1);
addHead(list1, );
addHead(list1, );
addHead(list1, );
addHead(list1, );
addHead(list1, );
dispList(list1);
printf("the second:\n");
deleNode(list1, );
dispList(list1);
printf("The length: %d\n", getLength(list1));
Node *node = getNode(list1, );
printf("The getNode result: %d\n", node->data); return ;
}

  测试完成功能正常。

  

40深入理解C指针之---指针与单链表的更多相关文章

  1. 00深入理解C指针之--- 指针之外

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. C语言从诞生之初就非常善于和硬件打交道,经过这么多年的发展之后,其灵活性和超强的特征是 ...

  2. 02深入理解C指针之---指针类型和值

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 1.指针的类型: 可以在声明指针时,指定指针的类型,例如: (1)void *x  声 ...

  3. 06深入理解C指针之---指针操作和比较

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针作为一种特殊类型的变量,必须遵守C语言中变量先声明后使用的原则.本节内容中指针的操 ...

  4. 10深入理解C指针之---指针运算和比较

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针运算有很多种,主要有指针的声明*.指针的解引*.指针指向(*).或->.指针 ...

  5. 理解C语言中指针的声明以及复杂声明的语法

    昨天刚把<C程序设计语言>中"指针与数组"章节读完,最终把心中的疑惑彻底解开了.如今记录下我对指针声明的理解.顺便说下怎样在C语言中创建复杂声明以及读懂复杂声明. 本文 ...

  6. 这样子来理解C语言中指针的指针

    友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...

  7. 从四个属性的角度来理解C语言的指针也许会更好理解

    文章会在文末更新! 关于指针是什么,很多教材已经作出了定义,大多数都会定义为"存放变量内存地址的变量".从这句话中我觉得除了让我知道这个定义有11个字以外,其他就没什么用了.我个人 ...

  8. 理解git 中的HEAD指针&branch指针

    理解git 中的HEAD指针&branch指针 Yooye关注 2019.02.28 10:44:32字数 492阅读 668 HEAD指针 使用git checkout 来移动HEAD指针, ...

  9. 深入理解C语言-函数指针

    函数指针在C++中有着重要的应用,函数的函数名其本质就是代表一个地址,这个地址叫做函数入口,得到这个地址就可以对这个函数进行各种操作. 函数类型基础 函数三要素: 名称.参数.返回值 C语言中的函数有 ...

随机推荐

  1. 巧用 Odoo act_window 的 flags实现一些个性化的视图控制

    转自:http://www.khcloud.net:4082/?thread-58.htm 'flags': { 'sidebar': False, //是否显示sidebar区域(主要为action ...

  2. 【NOIP2017提高A组冲刺11.8】好文章

    #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> us ...

  3. .pyc文件的结构体PyCodeObject

    python执行程序时生成的pyc文件里面是,PyCodeObject 的结构体构成,每个命名空间(函数名.import模块等)都会形成一个core block,一个python程序的所有命名空间生成 ...

  4. Docker 容器的跨主机连接

    使用网桥实现跨主枳容器连接 不推荐 使用OpenvSwitch实现跨主机容器连接 OpenvSwitch: OpenvSwitch是一个高质量的.多层虚拟交换枳,使用开源Apache2.0许可协议,由 ...

  5. spring事务(Transaction )报 marked as rollback-only异常的原因及解决方法

    很多朋友在使用spring+hibernate或mybatis等框架时经常遇到报Transaction rolled back because it has been marked as rollba ...

  6. LeetCode(234) Palindrome Linked List

    题目 Given a singly linked list, determine if it is a palindrome. Follow up: Could you do it in O(n) t ...

  7. STM32F407VET6之IAR之ewarm7.80.4工程建立(基于官方固件库1.6版本)

    今天把stm32F407的工程之IAR建立完成了,特此记录下. 下载官方固件库,STM32F4xx_DSP_StdPeriph_Lib_V1.6.1,V1.8.0版本的同理.新建以下几个文件 src放 ...

  8. URAL - 2065 Different Sums (思维题)

    题意: 给n和k,让你用不小于 k 个不同的数字构成一个长度为n的序列,使得序列中不同的区间和的数目最小. n,k<=500 k-1个数填一些数字的一正一负,这样有些区间和为0. 剩下的都填0. ...

  9. Python中的并发

    目录 Python并发 并发三种层次 协程 生成者消费者 新关键字 网络io 线/进程 例子 线程池 进程通信 并发池 future对象 executor对象 参考 Python并发 并发三种层次 个 ...

  10. 笔记-python-centos环境下安装配置

    笔记-python-centos环境下安装配置 1.      准备工作 环境准备 centos6.5 mini,已有python 2.6.6 下载源码包 Python官网下载Gzipped sour ...