【数据结构郝斌】3、模块一:线性结构
2017-02-27 11:03
106 查看
1、连续存储(数组)
1)什么叫数组
元素类型相同,大小相等。
2)数组的优缺点
优点:存取速度快
缺点:事先必须知道数组的长度,插入删除元素慢,空间通常是有限制,需要大块连续内存。
练习代码见:数据结构数组算法.c
确定一个数组需要几个信息:
数组首地址
数组长度
有效位数
2、离散存储(链表)
1)链表优缺点:
优点:空间没有限制,插入删除元素快
缺点:存取速度很慢。
2)预备知识:typedef的用法:
树与图都是靠链表实现的,所以,链表非常重要。
3)定义:
n个节点离散分配
彼此通过指针相连
每个节点只有一个前去节点,每个节点只有一个后续节点。
首节点没有前驱结点,尾节点没有后续节点。
专业术语:
首节点:
第一个有效节点
尾节点:
最后一个有效节点,指向下一个元素的指针为空。
头节点:
头节点数据类型与首节点数据类型相同
第一个有效节点前的节点
不存放有效数据
目的主要是为了方便对链表的操作。
头指针:
指向头结点的指针变量
尾指针:
指向尾节点的指针变量
如果希望通过一个函数来对链表进行处理,我们至少徐亚接收链表的那些参数(确定一个链表需要几个参数):
只需要一个参数:头指针
因为我们通过头指针可以推算出链表的其他所有信息。
链表的定义:
4)分类:
单链表:
双链表:
每个节点有两个指针域,指向前一个与后一个节点。
循环链表:
能通过任何一个节点找到其他所有的节点。
非循环链表:
5)算法:
遍历
查找
清空
销毁
求长度
排序
删除节点:
![](https://img-blog.csdn.net/20170227110201364?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva29uZ3pob25nbG91Y3Nkbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
插入节点:
将新的节点q插入链表中p的后边:
![](https://img-blog.csdn.net/20170227110220927?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva29uZ3pob25nbG91Y3Nkbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
算法:
狭义的算法与数据存储方式密切相关
广义的算法与数据存储方式无关
泛型:
利用某种技术达到的效果就是:不同的存储方式,执行的操作时一样的。
学算法,最重要的不是自己编算法,重要的是看懂已有的算法。重要的是看懂答案。
3、线性结构的两种常见结构一:栈
定义
一种可以实现“先进后出”的存储结构
栈类似于箱子,
分类
静态栈
动态栈(用的较多)
算法
出栈
压栈
每次压栈都压入栈顶
应用
函数调用
中断
表达式求职
内存分配
缓冲处理
迷宫
4、线性结构的两种常见结构二:队列
5、专题:递归
1)1+2+3+4….100的和(递归与循环的转换)
2)求阶乘
3)汉诺塔
4)走迷宫
6、相关代码:
1//链表操作代码
2//数据存储位置相关代码
3//栈操作相关代码
int a[10]; int *pArr = (*int
1)什么叫数组
元素类型相同,大小相等。
2)数组的优缺点
优点:存取速度快
缺点:事先必须知道数组的长度,插入删除元素慢,空间通常是有限制,需要大块连续内存。
练习代码见:数据结构数组算法.c
确定一个数组需要几个信息:
数组首地址
数组长度
有效位数
2、离散存储(链表)
1)链表优缺点:
优点:空间没有限制,插入删除元素快
缺点:存取速度很慢。
2)预备知识:typedef的用法:
typedef struct Student { int sid; char name[100]; char sex; }*PST,ST; //ST等价于struct Student,PST等价于:struct Student * //给 struct Student类型的指针PST //此时PST等价于:struct Student * 是一个指针
树与图都是靠链表实现的,所以,链表非常重要。
3)定义:
n个节点离散分配
彼此通过指针相连
每个节点只有一个前去节点,每个节点只有一个后续节点。
首节点没有前驱结点,尾节点没有后续节点。
专业术语:
首节点:
第一个有效节点
尾节点:
最后一个有效节点,指向下一个元素的指针为空。
头节点:
头节点数据类型与首节点数据类型相同
第一个有效节点前的节点
不存放有效数据
目的主要是为了方便对链表的操作。
头指针:
指向头结点的指针变量
尾指针:
指向尾节点的指针变量
如果希望通过一个函数来对链表进行处理,我们至少徐亚接收链表的那些参数(确定一个链表需要几个参数):
只需要一个参数:头指针
因为我们通过头指针可以推算出链表的其他所有信息。
链表的定义:
typedef struct Node { int data; //数据域 struct Node *pNext; //指针 }NODE,*PNODE; //NODE等价于struct Node, PNODE等价于struct Node *
4)分类:
单链表:
双链表:
每个节点有两个指针域,指向前一个与后一个节点。
循环链表:
能通过任何一个节点找到其他所有的节点。
非循环链表:
5)算法:
遍历
查找
清空
销毁
求长度
排序
删除节点:
p->pNext = p->pNext->pNext; //内存泄漏(p后边节点的内存没释放) 不能free(p->pNext); 正确做法: r = p->pNext; //r指向p后面的那个节点 p->pNext = r->pNext; free(p->->pNext);
插入节点:
将新的节点q插入链表中p的后边:
r = p->pNext; p->pNext = q; q->pNext = r ; 或:q->pNext = p->pNext; p->pNext = q;
算法:
狭义的算法与数据存储方式密切相关
广义的算法与数据存储方式无关
泛型:
利用某种技术达到的效果就是:不同的存储方式,执行的操作时一样的。
学算法,最重要的不是自己编算法,重要的是看懂已有的算法。重要的是看懂答案。
3、线性结构的两种常见结构一:栈
定义
一种可以实现“先进后出”的存储结构
栈类似于箱子,
分类
静态栈
动态栈(用的较多)
算法
出栈
压栈
每次压栈都压入栈顶
应用
函数调用
中断
表达式求职
内存分配
缓冲处理
迷宫
4、线性结构的两种常见结构二:队列
5、专题:递归
1)1+2+3+4….100的和(递归与循环的转换)
2)求阶乘
3)汉诺塔
4)走迷宫
6、相关代码:
1//链表操作代码
2//数据存储位置相关代码
3//栈操作相关代码
//链表操作代码 #include <stdio.h> #include <malloc.h> #include <stdlib.h> struct Node { int data; //数据与 struct Node *pNext; //指针域 }NODE ,*PNODE; //NODE 等价于struct Node PNODE等价于struct Node* //函数声明 PNODE create_list(void); //创建链表 void traverse_list(PNODE pHead); //遍历链表 bool is_empty(PNODE pHead); //判断链表为空 int length_list(PNODE); //判断链表长度 bool insert_list(PNODE,int,int); //插入 //在pHead所指向链表的第pos个节点的前面插入一个新的节点,该节点的值是val,并且pos的值从1开始。 bool delete_list(PNODE,int,int *); //删除 void sort_list(PNODE); //排序 int main(void) { PNODE pHead = NULL; //等价于struct Node* pHead = NULL; pHead = create_list() //创建一个非循环单链表,并将该链表的头结点的地址赋给pHead traverse_list(pHead); //遍历链表 //输出链表长度 int len = length_list(pHead); printf("链表长度是%d",len); //判断链表是否为空 if(is_empty(PNODE)) printf("链表为空"); else printf("链表不为空"); sort_list(pHead); //排序 traverse_list(pHead); //遍历链表 return 0; } PNODE create_list(void) { int len,i,val; //分配了一个不存放有效数据的头节点 PNODE pHead = (PNODE)malloc(sizeof(NODE)); if(NULL == pHead) { printf("分配失败"); exit(-1); } //定义一个指向尾节点的指针 PNODE pTail = pHead; pTail->pNext = NULL; printf("输入要生成链表节点的个数 : len = "); scanf("%d",%len); for(i=0;i<len;i++) { printf("请输入第%d个节点的值:",i+1); scanf("%d",&val); PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(NULL == pNew) { printf("分配失败"); exit(-1); } pNew->data = val; pTail->pNext = pNew; pNew->pNext = NULL; pTail = pNew; } return pHead; } void traverse_list(PNODE pHead) { PNODE p = pHead->pNext; while(NULL!=p) { printf("%d ",p->data); p = p->pNext; } printf("\n"); return; } bool is_empty(PNODE pHead) { if(NULL == pHead->pNext) return true; else return false; } int length_list(PNODE pHead) { PNODE p = pHead->pNext; int cnt; while(NULL!=p) { cnt ++; p= p->pNext; } return cnt; } void sort_list(PNODE pHead) { int i, j, t; PNODE p,q; int len = length_list(pHead); for(i=0,p = pHead->pNext;i<len-1;++i,p = p->pNext) { for(j=i+1,q = p->pNext;j<len;++j,q = q->pNext) { if(p->data > q->pNext) { t = p->data; //类似于t=a[i]; p->data = q->data; //类似于a[i]=a[j]; q->data = t; //类似于a[j]=t; } } } } //在pHead所指向链表的第pos个节点的前面插入一个新的节点,该节点的值是val,并且pos的值从1开始。 bool insert_list(PNODE pHead,int pos,int val) //插入 { int i=0; PNODE p = pHead; while(NULL !=p && i<pos-1) { p=p->pNext; ++i; }//指针p指向第pos个或最后一个节点。 if(i>pos-1 || NULL = p)//pos小于1或pos大于链表长度 return false; PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(NULL== pNew) { printf("动态分配内存失败!"); exit(-1); } pNew->data = val; // pNew插入链表中 PNODE q = p->pNext; p->pNext = pNew; pNew->pNext = q; retuen true; } bool delete_list(PNODE pHead,int pos,int *pVal) //删除 { int i=0; PNODE p = pHead; while(NULL !=p->pNext&& i<pos-1) { p=p->pNext; ++i; }//指针p指向第pos-1个或最后一个节点。 if(i>pos-1 || NULL = p->pNext)//pos小于1或pos大于链表长度 return false; PNODE q = p->pNext; *pVal = q->data; //删除p节点后边的节点 p->pNext = p->pNext->pNext; free(q); q = NULL; retuen true; }
//数据存储位置相关代码 #include<stdio.h> #include<malloc.h> void f(int k) { int m; double *q = (doble *)malloc(200); } int main(void) { int i = 10; int *p = (int *)malloc(100); return 0; } //代码中 i、p、m、q,在栈里分配 //malloc开辟的100个,200个内存在堆里分配 //栈里的内存程序自动分配,动态内存需要程序员手动分配
//栈操作相关代码 /* 创建 压栈 出栈 遍历 清空 */ #include<stdio.h> #include<malloc.h> #include<stdlib.h> typedef struct Node { intdata; struct Node *pNext; }NODE, * PNODE; struct Stack { PNODE pTop; //指向栈顶 PNODE pBottom; //指向栈底 }STACK,* PSTACK; void init(PSTACK); void push(PSTACK pS,int val); void traverse(PSTACK); bool pop(PSTACK,int *); //出栈 void clear(PSTACK pS); //框架还在,里边的元素都没了 int main(void) { STACK S; int val; init(&S); // 初始化 push(&S,1); //压栈,不能指定位置,只能压栈到栈底 push(&S,2); //压栈 traverse(&S); //遍历输出 clear(&S); //清空 traverse(&S); //遍历输出 if(pop(&S,&val)) //出栈 { printf("出栈成功,出栈元素是%d\n",val); } else { printf("出栈失败"); } return 0; } void init(PSTACK pS) { pS->pTop = (PNODE)malloc(sizeof(NODE)); //栈顶,头结点(无数据节点) if(NULL == pS->pTop) { printf("分配失败"); } else { pS->pBottom = pS->pTop; pS->pTop->pNext = NULL; //pS->Bottom->pNext = NULL } } void push(PSTACK pS,int val) { PNODE pNew = (PNODE)malloc(sizeof(NODE)); pNew->data = val; pNew->pNext = pS->pTop; //新节点插入到原栈顶上方 pS->pTop = pNew; //新节点成为栈顶 return; } void traverse(PSTACK pS) { PNODE p = pS->pTop; while(p != pS->pBottom) { printf("%d ",p->data); p=p->pNext; } printf("\n"); retrun ; } bool empty(PSTACK pS) { if(pS->pTop == pS->pBottom) return true; else return false; } //把pS所指向的栈出栈一次,并把出战的元素存入pVal形参所指向的变量中, bool pop(PSTACK pS,int *pval) //出栈 { if(empty(pS)) { return false; } else { PNODE r = pS->pTop; *pval = r->data; pS->pTop = r->pNext; free(r); r = NULL; return true; } } void clear(PSTACK pS) //框架还在,里边的元素都没了 { if(empty(pS)) { return ; } else { PNODE p = pS->pTop; PNODE q = p->pNext; while(p!=pS->pBottom) { q=p->pNext; free(p); p = q; } pS->pTop = pS->pTop; } /*自己写的代码 PNODE r; while(NULL != pS->pTop ) { r = pS->pTop; pS->pTop = r->pNext; free(r); } */ }
相关文章推荐
- 【郝斌数据结构自学笔记】57-59_递归8 _ 汉诺塔_1线性结构总复习 2线性结构和非线性结构关系 3栈队列链表数组之间的关系【重点】
- 【郝斌数据结构自学笔记】1-4_数据结构定义及特点
- 数据结构全攻略--线性结构不攻自破(一)
- 数据结构全攻略--线性结构不攻自破之栈和队列
- 软件设计师数据结构之线性结构复习小结
- 07-数据结构_线性结构-连续存储-数组
- 数据结构初学之----线性结构,树型…
- 数据结构 线性表的顺序结构
- Java数据结构与算法之数据结构-逻辑结构-线性结构(9)------Java线性结构概念及其基本操作
- PAT数据结构_02-线性结构3 Reversing Linked List (25分)
- PAT数据结构_02-线性结构4 Pop Sequence (25分)
- [数据结构]02-线性结构2 一元多项式的乘法与加法运算
- 考研笔记数据结构线性结构之C语言
- 数据结构 PAT 02-线性结构3 Pop Sequence
- 【数据结构】线性结构:栈&队列&数组
- 09-数据结构_线性结构-离散存储-链表_插删伪算法
- js 把线性的数据结构改成树形结构
- 郝斌数据结构(1)----数据结构基本分类和链表创建
- 数据结构(1) -- 线性结构
- 中国大学MOOC-陈越、何钦铭-数据结构-2015秋02-线性结构1题解