01 数据结构基本概念_大O表示法

无论n是多少都执行三个具体步骤

执行了12步 O(12)=>O(1)

O(n)

log 2 N = log c N / log c N (相当于两个对数进行了一次运算)

所以就不记入底数了,记作 O(logN)

资料:

(对数函数 a ≠ 1

O(logN)

O(n^2)

n+(n-1)+(n-2)+ … 1 = n*(n+1)/2

只关注最高次项n/2社区 n^2/2

O(n^2)

02 线性表基本概念

03 动态数组框架搭建

 

vector如何动态增长的:

1 当插入一个新的元素的时候 发现空间不足?

申请一块更大的内存空间

2 将原空间的数据拷贝到新的空间

3 释放旧的空间

4 把元素放入新的空间

  1. 1.      先创建头文件 DynamicArray.h:

里面定义好结构体 然后声明接口

2.DynamicArray.c:

 

 

04 动态数组框架实现

 

05 动态数组测试

dynamiclink.h:

dynamiclink.c:

source.c:

06 单向链表框架搭建

07 上午课程回顾

  1. 1.      算法的概念
  2. 2.      数据结构的概念

时间复杂度:

vector:

链表插入

newnode->next = pCurrent->next

pCureent->next = newnode

链表删除

pCurrent->next = pNext->next

free(pNext)

linklist.h:

#ifndef LINKLIST_H

#define LINKLIST_H

#include <stdlib.h>

#include <stdio.h>

// 链表节点

typedef struct LINKNODE {

void* data; // 指向任何类型的数据

struct LINKNODE * next;

}LinkNode;

// 链表结构体

typedef struct LINKLIST {

// 头结点

LinkNode * head;

int size;

// 需要容量吗? 没有容量的概念

} LinkList;

// 打印函数指针

typedef void(*PRINTLINKNODE) (void *);

// 初始化链表

LinkList * Init_ListList();

// 指定位置插入

void Insert_LinkList(LinkList * list,int pos,void * data);

// 删除指定位置的值

void RemoveByPos_LinkList(LinkList* list, int pos);

// 获得链表的长度

void Size_LinkList(LinkList * list);

// 查找

int Find_LinkList(LinkList *list,void *data);

// 打印链表节点

void Print_LinkList(LinkList * list,PRINTLINKNODE print);

// 返回第一个节点

void * Front_LinkList(LinkList * list);

// 释放链表内存

void FreeSpace_Linklist(LinkList * list);

#endif

 

linklist.c:

#include "Linklist.h"

// 打印函数指针

typedef void(*PRINTLINKNODE) (void *);

// 初始化链表

LinkList * Init_ListList()

{

// 进行初始化

// 在堆空间上分配链表结构体大小 初始化size为0

LinkList* list = (LinkList *)malloc(sizeof(LinkList));

// 初始化size为0

list->size = 0;

// 头结点 是不保存数据的

// 初始化一个结点 在堆空间上分配链表结点大小,将链表结构体的head指向该结点

list->head = (LinkNode *)malloc(sizeof(LinkNode));

// 初始化data为NULL

list->head->data = NULL;

// 初始化next为NULL

list->head->next = NULL;

// 返回链表结点

return list;

};

// 指定位置插入

void Insert_LinkList(LinkList * list, int pos, void * data)

{

if (list == NULL) {

return;

}

if (data == NULL) {

return;

}

// 友好的处理,pos越界

if (pos<0 || pos >list->size) {

// 如果越界了pos就是最大长度

pos = list->size;

}

// 创建新的结点

// 在堆空间分配链表结点

LinkNode * newnode = (LinkNode*)malloc(sizeof(LinkNode));

// 初始化data为data(注意:这里data的类型是void *

newnode->data = data;

// 初始化next为NULL

newnode->next = NULL;

// 找结点

// 辅助指针变量

// 辅助指针变量初始值为链表的第一个结点(即链表结构体head指向的结点

LinkNode *pCurrent = list->head;

// 假如传进来的pos是3 那么循环三次,找到pCurrent

for (int i = 0; i < pos; i++)

{

pCurrent = pCurrent->next;

}

// 新结点入链表

newnode->next = pCurrent->next;

pCurrent->next = newnode;

// 链表结构体的size++

list->size++;

};

// 删除指定位置的值

void RemoveByPos_LinkList(LinkList* list, int pos)

{

if (list == NULL) {

return;

}

if (pos <0 || pos >= list->size) {

return;

}

// 查找删除结点的前一个结点

LinkNode *pCurrent = list->head;

// 从第1个结点开始循环pos遍找到指定位置的链表结点

// 比如我要删除第2个,就要找到第2个

// 循环两边就指向了结点2

for (int i = 0; i < pos-1;i++) {

pCurrent = pCurrent->next;

}

// 缓存删除的结点

LinkNode * PDel = pCurrent->next;

pCurrent->next = PDel->next;

// 释放删除结点的内存

free(PDel);

list->size--;

};

// 获得链表的长度

void Size_LinkList(LinkList * list)

{

return list->size;

};

// 查找

int Find_LinkList(LinkList *list, void *data)

{

if (list == NULL) {

return -1;

}

if (data == NULL)

{

return -1;

}

// 遍历查找

LinkNode * pCurrent = list->head->next;

int i = 0;

while (pCurrent != NULL) {

if (pCurrent->data == data) {

break;

}

i++;

pCurrent = pCurrent->next;

}

return i;

};

// 打印链表节点

void Print_LinkList(LinkList * list, PRINTLINKNODE print)

{

if (list == NULL) {

return;

}

// 辅助指针变量

LinkNode* pCurrent = list->head->next;

while (pCurrent != NULL) {

print(pCurrent->data);

pCurrent = pCurrent->next;

}

};

// 返回第一个节点

void * Front_LinkList(LinkList * list){

return list->head->next->data;

};

// 释放链表内存

void FreeSpace_Linklist(LinkList * list) {

if (list == NULL) {

return;

}

// 辅助指针变量

LinkNode *pCurrent = list->head;

while (pCurrent != NULL) {

// 缓存下一个结点

LinkNode *pNext = pCurrent->next;

free(pCurrent);

pCurrent = pNext;

}

// 释放链表内存

list->size = 0;

free(list);

};

 

 

source.c:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "Linklist.h"

// 自定义数据类型

typedef struct PERSON {

char name[64];

int age;

int score;

} Person;

// 打印函数

void MyPrint(void * data) {

Person * p = (Person *)data;

printf("Name:%s Age:%d Score:%d\n", p->name, p->age, p->score);

}

int main(void)

{

// 创建链表

LinkList * list = Init_ListList();

// 创建数据

Person p1 = { "aaa",18,90 };

Person p2 = { "bbb",19,50 };

Person p3 = { "ccc",28,30 };

Person p4 = { "ddd",17,100 };

Person p5 = { "eee",16,23 };

// 数据插入链表

Insert_LinkList(list, 0, &p1);

Insert_LinkList(list, 0, &p2);

Insert_LinkList(list, 0, &p3);

Insert_LinkList(list, 0, &p4);

Insert_LinkList(list, 0, &p5);

// 打印

Print_LinkList(list, MyPrint);

// 删除3

RemoveByPos_LinkList(list, 3);

printf("\n");

Print_LinkList(list, MyPrint);

// 返回第一个结点

printf(" --------查找结果-------- \n");

Person * ret = (Person*)Front_LinkList(list);

printf("Name:%s Age:%d Score:%d\n", ret->name, ret->age, ret->score);

// 销毁链表

FreeSpace_Linklist(list);

printf("\n");

system("pause");

return 0;

}

09 单向链表测试

 

10 企业链表思路

 

衣服上的挂钩:

内核链表改进版 企业链表

把挂钩放在最上面了:

 

11 企业链表实现

 

内核链表因为把指针放到最下面了 所以还要计算偏移  实现企业级链表  把指针小结点放到结构体最开始,使用强制转换来取到LinkListNode

不用计算偏移

linklist.c:

#include "linklist.h"

// 初始化链表

LinkList * Init_LinkList()

{

// 在堆内存上初始化LinkList结构体大小的

LinkList *list = (LinkList*)malloc(sizeof(LinkList));

// 初始化head的next为NULL

list->head.next = NULL;

// 初始化size为0

list->size = 0;

return list;

}

// 插入

void Insert_LinkList(LinkList *list, int pos, LinkNode* data)

{

if (list == NULL) {

return;

}

if (data == NULL) {

return;

}

if (pos < 0 || pos > list->size) {

pos = list->size;

}

// 查找插入位置

// 辅助指针pCurrent是list的head的地址( 即那个小结点)

// 用LinkNode *类型的指针pCurrent指向这个第0个链表的小结点

LinkNode * pCurrent = &(list->head);

for (int i = 0; i < pos; i++)

{

pCurrent = pCurrent->next;

}

// 假设pos是2 那么从0移动到 2

// 插入新节点

data->next = pCurrent->next;

pCurrent->next = data;

list->size++;

}

// 删除

void Remove_LinkList(LinkList*list, int pos)

{

if (list == NULL) {

return;

}

if (pos<0 || pos >= list->size) {

return;

}

// 辅助指针变量

// LinkNode* 类型指针 指向第一个小结点

LinkNode *pCurrent = &(list->head);

for (int i = 0; i < pos; i++)

{

pCurrent = pCurrent->next;

}

// 删除结点

pCurrent->next = pCurrent->next->next;

list->size--;

}

// 查找

// 传入回调函数 定义的回调函数指针是COMPARENODE

int Find_LinkList(LinkList* list, LinkNode *data,COMPARENODE compare)

{

if (list == NULL) {

return;

}

if (data == NULL)

{

return;

}

// 辅助指针变量

LinkNode * pCurrent = list->head.next;

int index = 0;

int flag = -1;

while (pCurrent != NULL) {

if (compare(pCurrent, data) == 0) {

flag = index;

// 相等返回0

break;

}

pCurrent = pCurrent->next;

index++;

}

return flag;

}

// 返回链表大小

int Size_LinkList(LinkList * list)

{

return list->size;

}

// 打印

// 传入PRINTNODE类型回调函数

void Print_LinkList(LinkList *list, PRINTNODE print)

{

if (list == NULL) {

return;

}

// 辅助指针

LinkNode * pCurrent = list->head.next;

while (pCurrent != NULL)

{

print(pCurrent);

pCurrent = pCurrent->next;

}

}

// 释放链表内存

void FreeSpace_LinkList(LinkList *list)

{

if (list == NULL) {

return;

}

free(list);

}

linklist.h:

#ifndef LINKLIST_H

#define LINKLIST_H

#include <stdlib.h>

#include <stdio.h>

// 链表小结点

// 里面只有指针,指针指向小结点

typedef struct LINKNODE {

struct LINKNODE*next;

} LinkNode;

// 链表结点

typedef struct LINKLIST {

LinkNode head; // 链表小结点

int size;      // size大小

} LinkList;

// 初始化链表

LinkList * Init_LinkList();

// 插入

void Insert_LinkList(LinkList *list,int pos,LinkNode* data);

// 删除

void Remove_LinkList(LinkList*list,int pos);

// 查找

int Find_LinkList(LinkList* list,LinkNode *data,COMPARENODE compare);

// 返回链表大小

int Size_LinkList(LinkList * list);

// 打印

void Print_LinkList(LinkList *list,PRINTNODE print);

// 释放链表内存

void FreeSpace_LinkList(LinkList *list);

// 遍历函数指针

typedef void(*PRINTNODE) (LinkNode *);

// 比较函数指针

typedef int(*COMPARENODE) (LinkNode *, LinkNode *);

#endif

source.c:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "linklist.h"

typedef struct PERSON {

LinkNode node;

char name[64];

int age;

} Person;

void MyPrint(LinkNode * data) {

Person* p = (Person *)data;

printf("Name:%s Age:%d \n", p->name, p->age);

}

int MyCompare(LinkNode * node1, LinkNode* node2) {

Person *p1 = (Person *)node1;

Person *p2 = (Person *)node2;

if (strcmp(p1->name,p2->name) == 0 && p1->age == p2->age) {

return 0;

}

return -1;

}

int main(void) {

// 创建链表

// 在堆上初始化LinkList结构体大小

// Linklist的head指针 的next为NULL 初始化size值为0

LinkList * list = Init_LinkList();

// 创建数据

// 在栈上创建对象

Person p1, p2, p3, p4, p5;

strcpy(p1.name, "aaa");

strcpy(p2.name, "bbb");

strcpy(p3.name, "ccc");

strcpy(p4.name, "ddd");

strcpy(p5.name, "eee");

p1.age = 10;

p2.age = 20;

p3.age = 30;

p4.age = 40;

p5.age = 50;

// 将结点插入到链表

// list 在第0个位置插入data, 将p转成(LinkNode *)型的

Insert_LinkList(list, 0, (LinkNode *)&p1);

Insert_LinkList(list, 0, (LinkNode *)&p2);

Insert_LinkList(list, 0, (LinkNode *)&p3);

Insert_LinkList(list, 0, (LinkNode *)&p4);

Insert_LinkList(list, 0, (LinkNode *)&p5);

// 打印

Print_LinkList(list, MyPrint);

// 删除结点

Remove_LinkList(list,2);

// 打印

printf("===============\n");

Print_LinkList(list, MyPrint);

// 查找

Person findP;

strcpy(findP.name, "bbb");

findP.age = 20;

int pos = Find_LinkList(list, (LinkNode*)&findP, MyCompare);

printf("位置%d", pos);

// 释放链表内存

FreeSpace_LinkList(list);

system("pause");

return 0;

}

数据结构(1) 第一天 算法时间复杂度、线性表介绍、动态数组搭建(仿Vector)、单向链表搭建、企业链表思路的更多相关文章

  1. 【数据结构与算法】线性表操作(C++)

    #include <stdio.h> #define maxSize 100 //定义整型常量maxSize值为100 /*顺序表的结构体定义*/ typedef struct SqLis ...

  2. Java数据结构与算法(1):线性表

    线性表是一种简单的数据类型,它是具有相同类型的n个数据元素组成的有限序列.形如如A0,A1,...,An-1.大小为0的表为空表,称Ai后继Ai-1,并称Ai-1前驱Ai. printList打印出表 ...

  3. c数据结构 -- 线性表之 顺序存储结构 于 链式存储结构 (单链表)

    线性表 定义:线性表是具有相同特性的数据元素的一个有限序列 类型: 1:顺序存储结构 定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构 算法: #include <stdio. ...

  4. 线性表(存储结构数组)--Java 实现

    /*线性表的数组实现 *特点:插入删除慢需要平均移动一半的数据,查找较快 *注意:有重复和无重复的数据对应的操作会有些不同 *注意数组一旦创建其大小就固定了 *Java集合长度可变是由于创建新的数组将 ...

  5. 【数据结构与算法】线性表操作(C语言)

    #include <stdio.h> #include <stdlib.h> #define OK 1 #define NO 0 #define MAXSIZE 20 type ...

  6. "《算法导论》之‘线性表’":基于数组实现的单链表

    对于单链表,我们大多时候会用指针来实现(可参考基于指针实现的单链表).现在我们就来看看怎么用数组来实现单链表. 1. 定义单链表中结点的数据结构 typedef int ElementType; cl ...

  7. 有序线性表(存储结构数组)--Java实现

    /*有序数组:主要是为了提高查找的效率 *查找:无序数组--顺序查找,有序数组--折半查找 *其中插入比无序数组慢 * */ public class MyOrderedArray { private ...

  8. 线性表之顺序存储结构(C语言动态数组实现)

    线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...

  9. 算法与数据结构(一) 线性表的顺序存储与链式存储(Swift版)

    温故而知新,在接下来的几篇博客中,将会系统的对数据结构的相关内容进行回顾并总结.数据结构乃编程的基础呢,还是要不时拿出来翻一翻回顾一下.当然数据结构相关博客中我们以Swift语言来实现.因为Swift ...

随机推荐

  1. ubuntu--Supervisor的简单使用

    安装,这个程序使用python写的 sudo apt-get install supervisor 配置一个你需要的配置文件 //进入 /etc/supervisor/conf.d文件目录,配置一个r ...

  2. 关于double类型数字相加位数发生变化的问题

     因为计算机内部存贮本身的缺陷,导致double类型的数字相加.得到的结果有非常多位,比方 774.23 750.0 2638.66 4162.889999999999 看到这个是不是非常晕 当然 ...

  3. POJ 2486

    因为苹果可能在不同的子树中,所以,很容易想到设状态dp_back[i][j]为以i点为树根走j步并回到i点的最大苹果数与dp_to[i][j]不回到i点的两个状态. 于是,转移方程就很明显了.只是注意 ...

  4. Python:利用 selenium 库抓取动态网页示例

    前言 在抓取常规的静态网页时,我们直接请求对应的 url 就可以获取到完整的 HTML 页面,但是对于动态页面,网页显示的内容往往是通过 ajax 动态去生成的,所以如果是用 urllib.reque ...

  5. XTU OJ 1207 Welcome to XTCPC (字符串签到题)

    Problem Description Welcome to XTCPC! XTCPC start today, you are going to choose a slogan to celebra ...

  6. 让cocos2dx支持并通过arm64 编译

    为了要支持64位,请把这个文件直接替换到相应的lib文件夹下.本来是须要改neton_matrix_impl.c里的宏定义, 在 platform/ios/EAGLVIEW.mm中 在neon_mat ...

  7. 使用imgareaselect 辅助后台进行图片裁剪

    由于项目其中用到图片裁剪,本来能够不用到后台进行裁剪的,可是要兼容万恶的IE浏览器,所以不得不使用后台进行裁剪. 这次使用到imgareaselect 插件获取须要裁剪区域的坐标.再由后台进行裁剪操作 ...

  8. oc23--变量修饰符

    // // Person.h #import <Foundation/Foundation.h> /* @public:所有类访问 @private:本类访问 @protected:本类子 ...

  9. eclipse中的.project 和 .classpath文件的具体作用

    .project是项目文件,项目的结构都在其中定义,比如lib的位置,src的位置,classes的位置 .classpath的位置定义了你这个项目在编译时所使用的$CLASSPATH 这些文件你用文 ...

  10. [Hacker] 端口大全

    一 .端口大全 端口:0 服务:Reserved 说明:通常用于分析操作系统.这一方法能够工作是因为在一些系统中“0”是无效端口,当你试图使用通常的闭合端口连接它时将产生不同的结果.一种典型的扫描,使 ...