# include <stdio.h>
# include <stdbool.h>
# include <malloc.h> typedef int DataType; typedef struct Node {
DataType data;
struct Node * next;
} Node; /* 需要完成的所有基本操作 */
void InitList_Head(Node **);
void InitList_Tail(Node **);
int Length(Node *);
int LocateElem(Node *, DataType);
DataType GetElem(Node *, int);
bool ListInsert(Node *, int, DataType);
bool ListDelete(Node *, int, DataType *);
void PrintList(Node *);
bool Empty(Node *);
void DestroyList(Node *); int main(void) { printf("-insert head-\n");
Node * pHead1;
InitList_Head(&pHead1);
PrintList(pHead1);
printf("\n"); printf("-insert tail-\n");
Node * pHead2;
InitList_Tail(&pHead2);
PrintList(pHead2);
printf("size? %d\n", Length(pHead2));
printf("locate 2? %d\n", LocateElem(pHead2, 6));
printf("GetElem loc 4? %d\n", GetElem(pHead2, 4));
printf("\n"); printf("-insert elem-\n");
ListInsert(pHead2, 4, 0);
PrintList(pHead2);
printf("\n"); printf("-delete elem-\n");
int e;
ListDelete(pHead2, 4, &e);
printf("delete elem? %d\n", e);
PrintList(pHead2);
printf("\n"); printf("empty? %d\n", Empty(pHead2));
printf("\n"); printf("-delete elem-\n");
DestroyList(pHead2);
printf("empty? %d\n", Empty(pHead2));
PrintList(pHead2); return 0;
} void InitList_Head(Node ** ppHead) {
/*
1. 建立头结点
2. 循环插入 (头插法)
*/ Node * pHead = (Node *)malloc(sizeof(Node));
/*
此时,pHead中是头结点的地址
*/
pHead->next = NULL;
pHead->data = 9999; // for test int len = 5;
Node * pNew;
for (int i = 0; i < len; i++) {
pNew = (Node *)malloc(sizeof(Node));
pNew->data = i + 1;
pNew->next = pHead->next;
pHead->next = pNew;
} *ppHead = pHead;
return;
} void PrintList(Node * pHead) {
Node * p = pHead->next;
int i = 0; // just for test
/*
注意!!!
pHead存的是头结点的地址 但,
p存的不是pHead存的地址 --> 即头结点的地址
p存的是pHead指向的那个单元中next存的地址 --> 即第一个单元的地址
*/ printf("List's info:\n");
while ((p != NULL) && (i <= 10)) {
printf("data=%d, next=%d\n", p->data, p->next);
p = p->next; i++;
} return;
} void InitList_Tail(Node ** ppHead) {
Node * pHead = (Node *)malloc(sizeof(Node));
pHead->next = NULL;
pHead->data = 999; // just for test int len = 5;
Node * pNew;
Node * pTail = pHead;
for (int i = 0; i < len; i++) {
pNew = (Node *)malloc(sizeof(Node));
pNew->data = i + 10;
pNew->next = NULL; pTail->next = pNew;
pTail = pNew;
} *ppHead = pHead;
return;
} int Length(Node * pHead) {
int len = 0;
Node * p = pHead->next; while (p != NULL) {
len++;
p = p->next;
} return len;
} int LocateElem(Node * pHead, DataType d) {
int loc = 0;
Node * p = pHead->next; while (p != NULL && p->data != d) {
/*
四种情况:
p == NULL && p->data == d --> 跳出循环 --> 尾结点是目标点
p == NULL && p->data != d --> 跳出循环 --> 没有目标点
p != NULL && p->data == d --> 跳出循环 --> 尾结点前是目标点
p != NULL && p->data != d --> 继续循环
*/
p = p->next;
loc++;
} if (p == NULL || p->data != d) {
/*
判定条件不能只写(p->data != d)
因为,若此时p是NULL,则不能访问p->data
*/
return -1; // 没有这个点
} return loc;
} DataType GetElem(Node * pHead, int pos) {
Node * p = pHead->next;
int i = 1; if (pos <= 0) return -888; while(p != NULL) { if (i == pos) {
return p->data;
} p = p->next;
i++; } return -999;
} bool ListInsert(Node * pHead, int pos, DataType d) {
if (pos <= 0) return false; Node * p = pHead->next;
Node * pPrior = pHead;
int i = 1; while(p != NULL) {
if (i == pos) {
Node * pNew = (Node * )malloc(sizeof(Node));
pNew->data = d;
pNew->next = p;
pPrior->next = pNew; return true;
} p = p->next;
pPrior = pPrior->next;
i++;
} return false;
} bool ListDelete(Node * pHead, int pos, DataType * d) {
if (pos <= 0) return false; Node * p = pHead->next;
Node * pPrior = pHead;
int i = 1; while (p != NULL) {
if (i == pos) {
*d = p->data;
pPrior->next = p->next; free(p);
p=NULL; return true;
} p = p->next;
pPrior = pPrior->next;
i++;
} return false;
} bool Empty(Node * pHead) {
if (pHead->next == NULL) return true; return false;
} void DestroyList(Node * pHead) {
pHead->next = NULL;
}

数据结构_C语言_单链表的更多相关文章

  1. 数据结构C语言版--单链表的基本功能实现

    /* * 构造一个链式存储的线性表(当输入9999时,结束构造过程),然后输出该线性表 * 并统计该线性链表的长度 . *注:new和delete是C++的运算符 malloc和free是C++/C的 ...

  2. 数据结构_C语言_二叉树先序、中序、后序遍历

    # include <stdio.h> # include <stdlib.h> typedef struct BiTreeNode { char data; struct B ...

  3. C语言实现单链表-03版

    在C语言实现单链表-02版中我们只是简单的更新一下链表的组织方式: 它没有更多的更新功能,因此我们这个版本将要完成如下功能: Problem 1,搜索相关节点: 2,前插节点: 3,后追加节点: 4, ...

  4. C/C++语言实现单链表(带头结点)

    彻底理解链表中为何使用二级指针或者一级指针的引用 数据结构之链表-链表实现及常用操作(C++篇) C语言实现单链表,主要功能为空链表创建,链表初始化(头插法),链表元素读取,按位置插入,(有序链表)按 ...

  5. C语言实现单链表-02版

    我们在C语言实现单链表-01版中实现的链表非常简单: 但是它对于理解单链表是非常有帮助的,至少我就是这样认为的: 简单的不能再简单的东西没那么实用,所以我们接下来要大规模的修改啦: Problem 1 ...

  6. C语言实现单链表,并完成链表常用API函数

    C语言实现单链表,并完成链表常用API函数: 1.链表增.删.改.查. 2.打印链表.反转打印.打印环形链表. 3.链表排序.链表冒泡排序.链表快速排序. 4.求链表节点个数(普通方法.递归方法). ...

  7. 选择排序_C语言_数组

    选择排序_C语言_数组 #include <stdio.h> void select_sort(int *); int main(int argc, const char * argv[] ...

  8. 插入排序_C语言_数组

    插入排序_C语言_数组 #include <stdio.h> void insertSort(int *); int main(int argc, const char * argv[]) ...

  9. 快速排序_C语言_数组

    快速排序_C语言_数组 #include <stdio.h> void quickSort(int *, int, int); int searchPos(int *, int, int) ...

随机推荐

  1. C# winform自己的窗体不抢夺其他窗体的光标

    在你的form里加入: protected override CreateParams CreateParams { get { var result = base.CreateParams; ; r ...

  2. Spring Framework 有哪些不同的功能?

    轻量级 - Spring 在代码量和透明度方面都很轻便.IOC - 控制反转 AOP - 面向 切面编程可以将应用业务逻辑和系统服务分离,以实现高内聚.容器 - Spring 负 责创建和管理对象(B ...

  3. 学习DNS(二)

    DNS出现及演化 网络出现的早期 是使用IP地址通讯的,那时就几台主机通讯.但是随着接入网络主机的增多,这种数字标识的地址非常不便于记忆,UNIX上就出现了建立一个叫做hosts的文件(Linux和w ...

  4. 顺利通过EMC实验(15)

  5. 《每周一点canvas动画》——3D点线与水波动画

    <每周一点canvas动画>--差分函数的妙用 每周一点canvas动画代码文件 好像上次更新还是十一前,这唰唰唰的就过去大半个月了,现在才更新实在不好意思.这次我们不涉及canvas 3 ...

  6. canvas离屏、旋转效果实践——旋转的雪花

    效果展示理论基础--"常见的canvas优化--模糊问题.旋转效果" 用离屏canvas画基础部分 1.封装画线函数 function drawLine(ctx,x1,y1,x2, ...

  7. 网络安全—xss

    1.xss的攻击原理 需要了解 Http cookie ajax,Xss(cross-site scripting)攻击指的是攻击者往Web页面里插入恶意html标签或者javascript代码.比如 ...

  8. Python窗口学习之搜索框美化

    初学tkinter,感觉这个插件虽然是做界面的,但是没有html,也没有android那么人性化 既没有画圆角长方形的办法也没有添加透明按钮的办法(可能是我没找到) 所以自己用canvas画了两个扇形 ...

  9. javaScript设计模式:发布订阅模式

    发布订阅模式的思想是在观察者模式的基础上演变而来,在观察者模式中客户端监听到对象某个行为就触发对应任务程序.而在发布订阅模式中依然基于这个核心思想,所以有时候也会将两者认为是同一种设计模式.它们的不同 ...

  10. 如何查看k8s相关日志

    一.看系统日志cat /var/log/messages 二.用 kubectl 查看日志 # 注意:使用Kubelet describe 查看日志,一定要带上 命名空间,否则会报如下错误[root@ ...