1. 数组的优缺点

数组元素是连续的存储在有限的内存里,这样有两个缺点:

--数组的大小是有限的。如果需要给数组的内存(缓冲区buffer)扩容,需要调用realloc()函数。realloc()的工作原理:在内部调用malloc()来分配一块新的内存,然后用循环将原先内存的内容拷贝到新内存,然后free()掉原来的内存,返回新内存的地址。

--不方便进行元素的插入与删除。因为元素连续存储,互相之间没有空余的内存。

当然数组也有一个优点:不需要多余的信息就可以依次遍历,因为元素在内存中连续分布。

2. 单链表

单链表是这样一种结构:

它在内存中分散存储,用指针来依次关联。

链表的每个节点都是一个结构体struct,至少包含两个元素。例如:

typedef struct node
{int n;struct node * next;
} node;

链表的每个节点(除首末节点外)都用一个指针指向下一个元素,无序,因此链表不能使用二分法来查找。只能遍历。

链表节点的插入与删除 比数组容易多了,因为数组元素连续存储,元素互相之间没有空余的内存。

插入与删除分为三类:

首元素,

中间元素,

尾元素

代码一点点补上。

--------------------------------------------

下面的代码其实用的是C,但是因为.c文件不支持指针的引用,所以就用了.cpp

Slist.cpp

#include "Slist.h"//建立节点
SListNode*
_buildNode(DataType x)
{SListNode* tmp = (SListNode*)malloc(sizeof(SListNode));tmp->data = x;tmp->next = NULL;return tmp;
}// 打印单链表
void
printSlist(SListNode* headNode)
{SListNode* curNode = headNode;while (curNode){printf("%d->", curNode->data);curNode = curNode->next;}printf("NULL\n");
}//尾插
void
pushBack(SListNode* & headNode, DataType x)
{// 1.空// 2.不为空if (headNode == NULL){headNode = _buildNode(x);}else{// 找尾SListNode* tail = headNode;while (tail->next != NULL){tail = tail->next;}tail->next = _buildNode(x);}
}//  尾删
void
popBack(SListNode* & headNode)
{//// 1.空// 2.一个节点// 3.多个节点//if (headNode == NULL){return;}else if (headNode->next == NULL){free(headNode);headNode = NULL;}else{// 找尾SListNode* tail = headNode;SListNode* prev = NULL;while (tail->next){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}
}//头插
void
pushFront(SListNode* & headNode, DataType x)
{// 1.空// 2.不空if (headNode == NULL){headNode = _buildNode(x);}else{SListNode* tmp = _buildNode(x);tmp->next = headNode;headNode = tmp;}
}//头删
void
popFront(SListNode* & headNode)
{//// 1.空// 2.一个节点// 3.一个以上的节点//if (headNode == NULL){return;}else if (headNode->next == NULL){free(headNode);headNode = NULL;}else{SListNode* tmp = headNode;headNode = headNode->next;// free 掉 tmp 指针指向的内存free(tmp);}
}// 插入中间节点
void
insertNode(SListNode* pos, DataType x)
{assert(pos);SListNode* tmp = _buildNode(x);tmp->next = pos->next;pos->next = tmp;
}// 删除中间的节点
void
deleteNode(SListNode*& headNode, SListNode* pos)
{assert(pos);assert(headNode);//pos为头结点if (headNode == pos){headNode = headNode->next;// free 掉 tmp 指针指向的内存free(pos);return;}SListNode* prev = headNode;while (prev){if (prev->next == pos){prev->next = pos->next;free(pos);break;}prev = prev->next;}
}

可见,链表需要指针来找到下一个节点,此外,链表每插入一个元素都要malloc,这样做的缺点是,效率低因为内存分配以及内存中内容的拷贝很占用CPU周期

Slist.h

#ifndef SLIST_H
#define SLIST_H#include<stdio.h>
#include<assert.h>
#include<malloc.h>typedef int DataType;struct SListNode
{DataType data;            // 数据struct SListNode* next;   //指向下一个节点的指针
};//建立节点
SListNode*
_buildNode(DataType x);// 打印单链表
void
printSlist(SListNode* headNode);//尾插
void
pushBack(SListNode * & headNode, DataType x);//  尾删
void
popBack(SListNode * & headNode);//头插
void
pushFront(SListNode * & headNode, DataType x);//头删
void
popFront(SListNode * & headNode);// 插入中间节点
void
insertNode(SListNode * pos, DataType x);// 删除中间的节点
void
deleteNode(SListNode * & headNode, SListNode* pos);#endif

main.cpp

#include "Slist.h"int
main(int argc, char const *argv[])
{SListNode * headNode = NULL;for(DataType i = 0; i != 10; ++i){pushBack(headNode, i);printSlist(headNode);}for(DataType i = 10; i != 20; ++i){pushFront(headNode, i);printSlist(headNode);}return 0;
}

哈佛大学公开课:计算机科学cs50 学习笔记(第12集:单链表,内存分配)相关推荐

  1. 哈佛大学公开课:计算机科学cs50 学习笔记及代码练习(第8集:冒泡,选择排序,递归)

    0. 前言 这门课讲的排序相当清楚,老师用很容易懂的方式讲原理,代码部分在linux下写,用gdb调试,这才是编程的学习方法.记得以前国内本科也学过,但根本没讲清楚.现在研究生又听这门公开课,发现把原 ...

  2. Open SAP 上 SAP Fiori Elements 公开课第一单元学习笔记

    Open SAP 课程地址 这门公开课的教学大纲: 第一单元:Painting the big picture 本课程将使用 SAP Fiori Elements 开发一系列的应用,如下图所示: Th ...

  3. 吴恩达机器学习公开课第一周学习笔记

    Octave是一种编程语言,旨在解决线性和非线性的数值计算问题.Octave为GNU项目下的开源软件,早期版本为命令行交互方式,4.0.0版本发布基于QT编写的GUI交互界面.Octave语法与Mat ...

  4. 【学习笔记】数据结构之单链表(先进先出、先进后出)

    先看下数据结构中一种重要的数据存储形式,链表,下面两段是来自百度百科:        链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列 ...

  5. 哈佛大学公开课:计算机科学cs50 学习笔记(第2集:数据表示与存储)

    视频网址:http://open.163.com/special/opencourse/cs50.html 1. 数据在计算机中的表示与存储 日常生活中用的是10进制数,如: 位 3 2 1 0 权重 ...

  6. 哈佛大学公开课:计算机科学cs50 学习笔记(第3集:C语言,编译器)

    1. 编译器 Compiler 将代码文本按照ASCII码转换为二进制文件 Linux 下用 gcc 或者 g++ 编译器 gcc hello.c    默认在当前路径下生成 a.out 可执行文件, ...

  7. 哈佛大学公开课:计算机科学cs50 学习笔记(第7集:数组,其它)

    1. 一个语法糖 string s1  = (i==1)? "bottle" : "bottles"; 代替if -else 2. 预处理宏定义 例如:#def ...

  8. 哈佛大学公开课:计算机科学cs50 学习笔记(第6集:C语言,RAM)

    1. 关于变量对内存的使用 #include <stdio.h>void swap(int, int);int main(void) {int x = 1;int y = 2;swap(x ...

  9. 哈佛大学公开课:计算机科学cs50 学习笔记及代码实现(第9集:归并排序)

    用递归算法实现归并排序 伪代码如下: if n < 2 return; else sort left half of elements; sort right half of elements; ...

  10. 哈佛大学公开课:计算机科学cs50 学习笔记(第4~5集:C语言,编译器)

    1. fflush()函数 此函数包含在stdio.h头文件中,用来强制将缓冲区中的内容写入文件. 函数原型:int fflush(FILE *stream) ; 函数功能:清除一个流,即清除文件缓冲 ...

最新文章

  1. Spring Boot项目部署到Heroku
  2. UVA 701 The Archeologists' Dilemma
  3. golang中的栈帧
  4. Python: How to Sort a List
  5. 怎么看python程序卡在哪里_Python程序卡住了
  6. 2017-2018 Northwestern European Regional Contest (NWERC 2017)
  7. mysql函数 字符长度限制_MySQL中使用group_concat()函数数据字符过长报错的问题解决方法...
  8. 【报告分享】2020年中国智慧城市发展研究报告.pdf(附下载链接)
  9. java redis jar_Java使用Redis
  10. SQL Server 删除数据表数据
  11. zzuli OJ 1047: 对数表
  12. Java绩效评语_导师评语(转) - Java, Only Java! - BlogJava
  13. 台式主机插入耳机没声音
  14. KMP的next迷思
  15. 麒麟信安系统chrome和360浏览器离线安装
  16. SonrLint常见解决方案
  17. matlabnbsp;蠓虫分类问题nbsp;amp;n…
  18. 产品经理必看电影:操作系统革命 Revolution OS
  19. 关于软碟通UltraISO制作Ubuntu系统盘无法启动,推荐制作启动盘使用免费软件rufus
  20. 尚硅谷java多线程

热门文章

  1. 王者服务器维护公告最新,王者荣耀3月12日更新维护公告 3.12全部更新内容改动汇总...
  2. POJ1734 Sightseeing trip floyd求最小环问题
  3. asterisk中Callback+DISA电话回拨应用释例
  4. 抖音本地生活服务商贴牌小程序
  5. Service系统服务(二):补充应用技巧、软连接与硬连接、man手册、zip备份、vim效率操作、自定义yum软件仓库、发布及测试yum仓库、编译安装软件包...
  6. ubuntu Docker无法使用zip unzip指令 解决方案
  7. 黏菌优化算法SMA与算术优化算法AOA及其联合改进
  8. Python-投骰子(random,plotly)
  9. 【个人博客的搭建】【从零开始】【零成本】Hexo + Gitee(有教程视频)
  10. Android开发_NFC