郝斌_数据结构_连续存储数组的算法事例 程序
郝斌数据结构自学笔记知识点+程序源代码
5_预备知识_指针_2
指针的重要性:
指针是C语言的灵魂
定义:
地址:
地址是内存单元的编号,从0开始的非负整数,范围:0-FFFFFFFF【0-4G-1】
CPU=====地址线,控制线,数据线=====内存
指针:
指针就是地址,地址就是指针。
指针变量是存放内存单元地址的变量。
指针的本质是一个操作受限的非负整数。
structStudent*pst=&st;
doublearr[3]={1.1,2.2,3.3};
double *q;
q=&arr[0];
printf(“%p\n”,q);//%p实际就是以十六进制输出
q=&arr[1];
q=printf(“%p\n”,q);//p,q相差8
无论指针指向的变量占多少个字节,指针变量统一都只占4个字节
7_如何通过函数修改实参的值
for (i=0;i<lem;i++)
printf(“%d\n”,p[i]);
}
指针变量的运算
指针变量不能相加,不能相乘,不能相除。
如果两指针变量属于同一数组,则可以相减。
指针变量可以加减一整数,前提是最终结果不能超过指针变量
p+i的值是p+i*(p所指向的变量所占的字节数)
p-i的值是p-i*(p所指向的变量所占的字节数)
//p=10;//error
ﻩj=*p;//等价于j=i;
ﻩprintf("i=%d,j=%d,*p=%d\n",i,j,*p);
ﻩreturn 0;
}
CASE2
#include<stdio.h>
“数据结构”读书笔记
“数据结构”读书笔记示例:第2章线性表学习线索:逻辑结构→基本运算定义→存储结构→基本运算实现(复杂度分析→应用实例)1. 逻辑结构:是由n(n≥0)个数据元素组成的有限序列。
2. 基本运算定义:(P.16)(1)Init_List(L),线性表初始化;(2)Length _ List (L),求线性表的长度;(3)Get_ List (L,i),取表元;(4)Locate_ List (L,x),按值查找;(5)Insert_ List (L,x,i);插入操作;(6)Delete_ List (L,i),删除操作。
3. 存储结构:(1)顺序表:把线性表的结点按逻辑次序存放在一组地址连续的存储单元里。
顺序存储的结构体定义:typedef struct{ datatype data[MAXSIZE]; /* 一维数组子域*/int last; /* 表长度子域*/} SeqList; /* 顺序存储的结构体类型*/4-1. 顺序表的基本运算的实现(算法及其复杂度分析、应用实例:顺序表的划分、合并、比较大小)(2)单链表:只有一个链域的链表称单链表。
结点结构:Data(节点值)Next(后继结点地址)其中data是数据域,next是指针域链式存储的结构体定义:typedef struct lnode{ datatype data; /* 数据子域*/struct lnode *next; /* 指针子域*/} LNode,*LinkList; /* 链式存储的结点结构类型*/4-2. 单链表的基本运算的实现(算法及其复杂度分析、应用实例:链表逆置、归并)单链表的发展:循环链表、双向链表顺序表和链表的比较1)基于空间:2)基于时间:“数据结构”读书笔记(线性结构部分)第1章绪论1. 数据:信息的载体,能被计算机识别、存储和加工处理。
2. 数据元素:数据的基本单位,可由若干个数据项组成,数据项是具有独立含义的最小标识单位。
郝斌老师__数据结构
append_arr(&arr, -3);
append_arr(&arr, 6);
append_arr(&arr, 88);
append_arr(&arr, 11);
if ( delete_arr(&arr, 4, &val) )
{
printf("删除成功!\n");
bool delete_arr(struct Arr * pArr, int pos, int * pVal);
int get();
bool is_empty(struct Arr * pArr);
bool is_full(struct Arr * pArr);
void sort_arr(struct Arr * pArr);
void g(struct Student st)
{
printf("%d %s %d\n", st.sid, , st.age);
}
void g2(struct Student *pst)
{
printf("%d %s %d\n", pst->sid, pst->name, pst->age);
//p[i]就是主函数的a[i]
}
int main(void)
{
int a[5] = {1,2,3,4,5};
Show_Array(a, 5); //a等价于&a[0], &a[0]本身就是int *类型
//printf("%d\n", a[2]);
return 0;
郝斌老师自学视频教程下载(c语言,JAVA, sql2005数据库,数据结构)
郝斌老师自学视频教程下载(c语言,JA V A, sql2005数据库,数据结构)郝斌老师C语言1-10.rar (55.18 MB)郝斌老师C语言11-20.rar (74.16 MB)郝斌老师C语言21-30.rar (74.06 MB)郝斌老师C语言31-39.rar (54.99 MB)郝斌老师C语言40-49.rar (55.41 MB)郝斌老师C语言50-60.rar (462.46 MB)郝斌老师C语言61-70.rar (77.08 MB)郝斌老师C语言71-80.rar (119.06 MB)郝斌老师C语言81-89.rar.rar (73.89 MB)郝斌老师C语言90-100.rar (79.27 MB)郝斌老师C语言101-120.rar (510.8 MB)郝斌老师C语言121-130.rar (199.7 MB)郝斌老师C语言131-150.rar (222.73 MB)郝斌老师C语言151-180.rar (966.1 MB)缺少的课.zip (59.9 MB)C视频源代码.rar (4.98 MB)C大纲.pdf (5.33 MB)该教程视频录制工具(使用前请先运行内置绿化工具).rar (28.31 MB)1_Java概述_1.rar (23.51 MB)2_Java概述_2.rar (7.5 MB)3_Java概述_3.rar (20.59 MB)4_Java的卸载.rar (3.04 MB)5_Java的安装.rar (5.97 MB)6_环境变量的设置.rar (25.53 MB)7_常见dos命令.文件名和类名不同时编译运行的问题.rar (11.92 MB)8_变量命名规则.数据类型.运算符.格式化输出.流程控制.rar (41.38 MB) 9_复习上节课.rar (9.31 MB)10_类和对象.rar (7.28 MB)11_内存分配.rar (22.49 MB)12_访问控制符_1.rar (11.84 MB)13_访问控制符_2.rar (9.5 MB)14_构造函数.rar (23.2 MB)15_UltraEdit的使用.rar (6.85 MB)16_复习.rar (4.5 MB)17_函数的重载.rar (6.88 MB)18_构造函数.rar (8.33 MB)19_this.rar (10.91 MB)20_static.rar (23.06 MB)21_复习.rar (6.56 MB)22_static两示例_求个数_只生成一个对象__1.rar (11.18 MB)23_static两示例_求个数_只生成一个对象__2.rar (11.88 MB)24_继承的由来.和.继承的访问控制权限_1.rar (7 MB)25_继承的由来.和.继承的访问控制权限_2.rar (10.32 MB)26_面向对象的继承反映的是现实中的一般到特殊的关系.rar (2.12 MB) 27_Java为什么没有多继承.rar (6.25 MB)28_复习.super_1.rar (16.38 MB)29_复习.super_2.rar (16.85 MB)30_重写父类方法_1.rar (15.52 MB)31_重写方法示例.rar (14.87 MB)32_多态的语法知识.rar (10.5 MB)33_复习.rar (8.59 MB)34_多态注意事项和.实际应用示例.rar (29.59 MB)35_抽象类.和.final.rar (36.83 MB)36_接口_1.rar (23.89 MB)37_接口_2.rar (18.73 MB)38_面向对象复习.rar (8.4 MB)39_编译运行含有包层的类_1.rar (14.59 MB)40_编译运行含有包层的类_2.rar (12.32 MB)41_同包和不同包类的相互访问.rar (20.18 MB)42_复习.和.不同包之间的相互访问_1.rar (14.66 MB)43_复习.和.不同包之间的相互访问_2.rar (25.81 MB)44_jar包的生成.avi.rar (22.32 MB)45_如何使用Jar包.和.包的总回顾.rar (18.09 MB)46_异常概述_1.rar (27.22 MB)47_异常概述_2.rar (24.18 MB)48_复习.rar (15.68 MB)49_为什么需要异常.rar (16.92 MB)50_printStackTrace方法的介绍.rar (8.83 MB)51_可处理可不处理的异常.和.必须得进行处理的异常.rar (13.87 MB) 52_处理异常的两种方式.rar (5.42 MB)53_finally.rar (10.41 MB)54_自定义异常.和.throws常见错误解析_1.rar (13.96 MB)55_自定义异常.和.throws常见错误解析_2.rar (14.34 MB)56_异常复习.rar (82.65 MB)57_异常.rar (88.81 MB)58_ToString()方法介绍_1.rar (77.48 MB)59_ToString()方法介绍_2.rar (8.55 MB)60_equals_1.rar (66.04 MB)61_equals_2.rar (77.03 MB)62_复习.rar (48.8 MB)63_String类的.equals==常量字符串的用法.rar (100.19 MB)64_String类的常用方法介绍.字符串和整数的相互转化.rar (105.64 MB) 65_String常用方法举例.rar (107.2 MB)66_printf和println的区别.rar (90.1 MB)67_复习.rar (3.62 MB)68_StringBuffer.rar (10.76 MB)69_数组.rar (20.96 MB)70_线程_1.rar (29.52 MB)71_复习.rar (4.85 MB)72_创建线程的第二种方式.rar (6.62 MB)73_线程常用方法的介绍.rar (5.37 MB)74_线程的控制.rar (33.35 MB)75_线程同步问题的产生原因.rar (12.48 MB)76_复习.rar (56.6 MB)77_买票程序讲解.rar (247.39 MB)78_闲聊.rar (34.71 MB)79_复习.rar (6.68 MB)80_生产消费_1.rar (38 MB)81_生产消费_2.rar (35.09 MB)82_awt展望.rar (7.1 MB)83_gui.rar (47.02 MB)84_布局管理器.rar (30.76 MB)85_事件处理.rar (34.74 MB)86_复习.rar (16.29 MB)87_十个按钮的设计.rar (53.34 MB)88_三个文本框的相加运算示例.rar (253.89 MB)89_复习.内部类.匿名类.rar (26.53 MB)90_计算器.可运行jar包的生成.rar (6.1 MB)91_什么叫流.流的分类.四大基本抽象流.rar (39.71 MB)92_复习.rar (13.79 MB)93_字节流.字符流的使用和它们的区别.rar (45.65 MB)94_缓冲流的使用.rar (49.57 MB)95_将一个长整型数据写入字节数组然后再从字节数组读出来.示例的讲解.rar (37.25 MB)96_print流.Object流.rar (43.78 MB)97_什么是容器.容器的分类.Collection的介绍.List.Set的区别.重写toString方法的必要性.Collections的使用.rar (46.06 MB)98_Comparable.接口.Set接口.rar (39.28 MB)99_.复习.rar (18.25 MB)100_equals和hashCode方法的使用(难点).rar (43.14 MB)101_Iterator接口.rar (9.71 MB)102_Map接口的使用.rar (35.11 MB)103_泛型.rar (16.1 MB)104_网络编程基础知识.UDP编程.rar (32.15 MB)105_TCP编程.和.TCP下的WEB服务器程序的讲解.rar (46.7 MB)106_JavaSE复习大纲.rar (58.21 MB)107_JavaSE复习大纲.rar (39.04 MB)源代码&PPT.rar (73.96 MB)郝斌数据结构自学视频_[1-60].rar (587.35 MB)郝斌数据结构自学视频【61-78】_视频完.rar (196.24 MB)[数据结构(C语言版)].严蔚敏_吴伟民.扫描版.pdf (28.95 MB)郝斌SqlServer_2005自学视频_全集.rar (823.53 MB)郝斌SqlServer2005自学视频的源代和大纲.rar (14.54 MB)1_我为什么要出视频.swf (2.99 MB)2_我对自学的一些看法.swf (7.04 MB)。
数据结构课程设计
前一部分为郝斌视频简单记录,后一部分为ppt内容,郝斌讲过的后面ppt中不再重复int * pArr = (int *)malloc(sizeof(int) * len);不同的存储结构算法也不同泛型模块一:线性结构连续存储【数组】程序Arr 视频12,13 (首地址长度有效值的个数)优点存取速度快缺点插入删除元素很慢空间通常是有限制的需要大块连续的内存事先必须知道数组的长度离散存储【链表】1.定义n个节点离散分配/ 彼此通过指针相连/ 每个节点只有一个前驱节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点首节点(第一个有效节点)尾节点头结点(数据类型和首节点相同,第一个有效节点之前的节点,不存放有效数据,为了方便对链表的操作)头指针(指向头节点的指针变量)尾指针确定一个链表需要几个参数:只需要一个参数即头指针通过头指针可以推算出链表其他的所有信息(头结点可能占太多内存)Node 节点的生成节点的数据类型如何表示typedef struct Node{int data;//数据域struct Node * pNext;//指针域和结构体本身的类型相同}NODE, *PNODE;//NODE等价于struct Node ,PNODE等价于struct Node *2.分类单链表双链表每一个节点有两个指针域循环链表能通过任何一个节点能找到其他所有的节点非循环链表3.算法# include <stdio.h># include <malloc.h># include <stdlib.h>typedef struct Node{int data;struct Node * pNext;}NODE, *PNODE;//函数声明PNODE creat_list(void);void traverse_list(PNODE pHead);int main(void){PNODE pHead = NULL;pHead = creat_list();//creat_list() 功能:创建一个非循环单链表,并将该链表的首地址赋给pHeadtraverse_list(pHead);return 0;}PNODE creat_list(void){int len;int i;int val;//分配了一个不存放有效数据的头结点PNODE pHead = (PNODE)malloc(sizeof(NODE));if (NULL == pHead){printf("分配失败,退出程序!\n");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("分配失败,退出程序!\n");exit(-1);}pNew->data = val;pTail->pNext = pNew;//把每个新生成的节点挂到尾节点pTail上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;}遍历查找清空销毁求长度排序删除节点r = p->pnext;p->pnext = p->pnext->pnext;free(r); 注意不能直接free(p->pnext)否则第二个节点丢失,链会断开插入节点(头结点后面插入p所指向的那个节点)p->next = head->next;head->next = p;算法:狭义的算法是与数据的存储方式密切相关广义的算法是与数据的存储方式无关泛型:利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的即同一种逻辑结构,无论该逻辑结构物理存储是什么样子的我们都可以对它执行相同的操作可以利用c++中函数重载,来定义函数使其完成不同数据类型的操作的处理,即:++(){p = p->pNext; //链表,区别于数组可以直接进行++运算,但此时他们的操作是}4.优缺点优点没有空间限制插入删除元素很快缺点存取速度很慢,需进行遍历才能找到栈和队列是两种常用的数据类型线性结构两种常见的应用之一栈stack定义一种可以实现“先进后出”的存储结构Top Bottom/Base指针由栈顶元素指向栈底元素分类静态栈以数组为内核动态栈以链表为内核,相当于一个操作受限的链表算法出栈压栈应用函数调用中断表达式求值-----计算器,课本程序内存分配缓冲处理迷宫静态内存栈程序自动分配压栈出栈的方式分配内存都是分配内存的方式动态内存堆如malloc 程序员申请的堆排序的方式分配内存课本讲解的两个应用1数制转换2表达式求值(需要操作数栈和运算符栈(栈底为#))前缀式的运算规则为:运算符在式中出现的顺序恰为表达式的运算顺序;连续出现的两个操作数和在它们之前且紧靠它们的运算符构一个最小表达式;后缀式的运算规则为:运算符在式中出现的顺序恰为表达式的运算顺序;每个运算符和在它之前出现且紧靠它的两个操作数构成一个最小表达式。
郝斌老师 数据结构
{数据结构1~5笔记}Array_point 1# include <stdio.h>int main(void){int a[5] = {1,2,3,4,5};//a[3] == *(3+a);printf("%p\n", a+1);printf("%p\n", a+2);printf("%d\n", *a+3); //*a+3等价于a[0]+3return 0;}Array_point 2# include <stdio.h>void Show_Array(int * p, int len){int i = 0;for (i=0; i<len; ++i)printf("%d\n", p[i]);//p[2] = -1; //p[0] == *p p[2] == *(p+2) == *(a+2) == a[2] //p[i]就是主函数的a[i]}int main(void){int a[5] = {1,2,3,4,5};Show_Array(a, 5); //a等价于&a[0], &a[0]本身就是int *类型//printf("%d\n", a[2]);return 0;}Point_1# include <stdio.h>int main(void){int * p; //p是个变量名字, int * 表示该p变量只能存储int类型变量的地址int i = 10;int j;// p = &i;j = *p; // 等价于j = i;printf("i = %d, j = %d, *p = %d\n", i, j, *p);//p = 10; //errorreturn 0;}Point 2# include <stdio.h>int main(void){int * p; //p是个变量名字, int * 表示该p变量只能存储int类型变量的地址int i = 10;int j;p = &i;*p = i; // 等价于i = i;// j = *p; // 等价于j = i;printf("i = %d, j = %d, *p = %d\n", i, j, *p);return 0;}Point3# include <stdio.h>void f(int * p) //不是定义了一个名字叫做*p的形参, 而是定义了一个形参,该形参名字叫做p,它的类型是int *{*p = 100; //}int main(void){int i = 9;f(&i);printf("i = %d\n", i);return 0;}{数据结构6~10笔记}# include <stdio.h>int main(void){double * p;double x = 66.6;p = &x; //x占8个子节1个字节是8位, 1个子节一个地址double arr[3] = {1.1, 2.2, 3.3};double * q;q = &arr[0];printf("%p\n", q); //%p实际就是以十六进制输出q = &arr[1];printf("%p\n", q);return 0;}# include <stdio.h>void f(int * p);int main(void){int i = 10;f(&i);printf("i = %d\n", i);return 0;}void f(int * p){*p = 99;}# include <stdio.h>void f(int ** q);int main(void){int i = 9;int * p = &i;// int *p; p = &i;printf("%p\n", p);f(&p);printf("%p\n", p);return 0;}void f(int ** q){*q = (int *)0xFFFFFFFF;}Malloc1# include <stdio.h># include <malloc.h>int main(void){int a[5] = {4, 10, 2, 8, 6};int len;printf("请输入你需要分配的数组的长度: len = ");scanf("%d", &len);int * pArr = (int *)malloc(sizeof(int) * len);// *pArr = 4; //类似于a[0] = 4;// pArr[1] = 10; //类似于a[1] = 10;// printf("%d %d\n", *pArr, pArr[1]);//我们可以把pArr当做一个普通数组来使用for (int i=0; i<len; ++i)scanf("%d", &pArr[i]);for (i=0; i<len; ++i)printf("%d\n", *(pArr+i));free(pArr); //把pArr所代表的动态分配的20个字节的内存释放return 0;}Memory1# include <stdio.h>int f();int main(void){int i = 10;i = f();printf("i = %d\n", i);for (i=0; i<2000; ++i)f();return 0;}int f(){int j = 20;return j;}Memory2# include <stdio.h># include <malloc.h>struct Student{int sid;int age;};struct Student * CreateStudent(void); void ShowStudent(struct Student *);int main(void){struct Student * ps;ps = CreateStudent();ShowStudent(ps);return 0;}void ShowStudent(struct Student * pst){printf("%d %d\n", pst->sid, pst->age);}struct Student * CreateStudent(void){struct Student * p = (struct Student *)malloc(sizeof(struct Student));p->sid = 99;p->age = 88;return p;}Struct1# include <stdio.h># include <string.h>struct Student{int sid;char name[200];int age;}; //分号不能省int main(void){struct Student st = {1000, "zhangsan", 20};printf("%d %s %d\n", st.sid, , st.age);st.sid = 99;// = "lisi"; //errorstrcpy(, "lisi");st.age = 22;printf("%d %s %d\n", st.sid, , st.age);//printf("%d %s %d\n", st); //errorreturn 0;}Struct2/*2009年8月26日14:18:02如何使用结构体两种方式:struct Student st = {1000, "zhangsan", 20};struct Student * pst = &st;1.st.sid2.pst->sidpst所指向的结构体变量中的sid这个成员*/# include <stdio.h># include <string.h>struct Student{int sid;char name[200];int age;}; //分号不能省int main(void){struct Student st = {1000, "zhangsan", 20};//st.sid = 99; //第一种方式struct Student * pst;pst = &st;pst->sid = 99; //第二种方式pst->sid 等价于(*pst).sid 而(*pst).sid等价于st.sid, 所以pst->sid 等价于st.sidreturn 0;}Struct3# include <stdio.h># include <string.h>struct Student{int sid;char name[200];int age;}; //分号不能省void f(struct Student * pst);void g(struct Student st);void g2(struct Student *pst);int main(void){struct Student st; //已经为st分配好了内存f(&st);g2(&st);//printf("%d %s %d\n", st.sid, , st.age);return 0;}//这种方式耗内存耗时间不推荐void g(struct Student st){printf("%d %s %d\n", st.sid, , st.age);}void g2(struct Student *pst){printf("%d %s %d\n", pst->sid, pst->name, pst->age);}void f(struct Student * pst){(*pst).sid = 99;strcpy(pst->name, "zhangsan");pst->age = 22;}{数据结构10~13笔记}# include <stdio.h># include <malloc.h> //包含了malloc函数# include <stdlib.h> //包含了exit函数//定义了一个数据类型,该数据类型的名字叫做struct Arr, 该数据类型含有三个成员,分别是pBase, len, cntstruct Arr{int * pBase; //存储的是数组第一个元素的地址int len; //数组所能容纳的最大元素的个数int cnt; //当前数组有效元素的个数};void init_arr(struct Arr * pArr, int length); //分号不能省bool append_arr(struct Arr * pArr, int val); //追加bool insert_arr(struct Arr * pArr, int pos, int val); // pos的值从1开始bool delete_arr(struct Arr * pArr, int pos, int * pV al);int get();bool is_empty(struct Arr * pArr);bool is_full(struct Arr * pArr);void sort_arr(struct Arr * pArr);void show_arr(struct Arr * pArr);void inversion_arr(struct Arr * pArr);int main(void){struct Arr arr;int val;init_arr(&arr, 6);show_arr(&arr);append_arr(&arr, 1);append_arr(&arr, 10);append_arr(&arr, -3);append_arr(&arr, 6);append_arr(&arr, 88);append_arr(&arr, 11);if ( delete_arr(&arr, 4, &val) ){printf("删除成功!\n");printf("您删除的元素是: %d\n", val);}else{printf("删除失败!\n");}/* append_arr(&arr, 2);append_arr(&arr, 3);append_arr(&arr, 4);append_arr(&arr, 5);insert_arr(&arr, -1, 99);append_arr(&arr, 6);append_arr(&arr, 7);if ( append_arr(&arr, 8) ){printf("追加成功\n");}else{printf("追加失败!\n");}*/show_arr(&arr);inversion_arr(&arr);printf("倒置之后的数组内容是:\n");show_arr(&arr);sort_arr(&arr);show_arr(&arr);//printf("%d\n", arr.len);return 0;}void init_arr(struct Arr * pArr, int length){pArr->pBase = (int *)malloc(sizeof(int) * length);if (NULL == pArr->pBase){printf("动态内存分配失败!\n");exit(-1); //终止整个程序}else{pArr->len = length;pArr->cnt = 0;}return;}bool is_empty(struct Arr * pArr){if (0 == pArr->cnt)return true;elsereturn false;}bool is_full(struct Arr * pArr){if (pArr->cnt == pArr->len)return true;elsereturn false;}void show_arr(struct Arr * pArr){if ( is_empty(pArr) ){printf("数组为空!\n");}else{for (int i=0; i<pArr->cnt; ++i)printf("%d ", pArr->pBase[i]); //int * printf("\n");}}bool append_arr(struct Arr * pArr, int val){//满是返回falseif ( is_full(pArr) )return false;//不满时追加pArr->pBase[pArr->cnt] = val;(pArr->cnt)++;return true;}bool insert_arr(struct Arr * pArr, int pos, int val) {int i;if (is_full(pArr))return false;if (pos<1 || pos>pArr->cnt+1) //return false;for (i=pArr->cnt-1; i>=pos-1; --i){pArr->pBase[i+1] = pArr->pBase[i];}pArr->pBase[pos-1] = val;(pArr->cnt)++;return true;}bool delete_arr(struct Arr * pArr, int pos, int * pV al) {int i;if ( is_empty(pArr) )return false;if (pos<1 || pos>pArr->cnt)return false;*pV al = pArr->pBase[pos-1];for (i=pos; i<pArr->cnt; ++i){pArr->pBase[i-1] = pArr->pBase[i];}pArr->cnt--;return true;}void inversion_arr(struct Arr * pArr){int i = 0;int j = pArr->cnt-1;int t;while (i < j){t = pArr->pBase[i];pArr->pBase[i] = pArr->pBase[j];pArr->pBase[j] = t;++i;--j;}return;}void sort_arr(struct Arr * pArr){int i, j, t;for (i=0; i<pArr->cnt; ++i){for (j=i+1; j<pArr->cnt; ++j){if (pArr->pBase[i] > pArr->pBase[j]){t = pArr->pBase[i];pArr->pBase[i] = pArr->pBase[j];pArr->pBase[j] = t;}}}}{数据结构14~22笔记}插入节点r = p->pNext; p->pNext = q; q->pNext = r;q->pNext = p->pNext; p->pNext = q;删除一个节点r = p->pNext;p->pNext = p->pNext->pNext;free(r);{数据结构23~28笔记}List上课敲的程序# include <stdio.h># include <malloc.h># include <stdlib.h>typedef 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;int val;pHead = create_list(); //create_list()功能:创建一个非循环单链表,并将该链表的头结点的地址付给pHeadtraverse_list(pHead);//insert_list(pHead, -4, 33);if ( delete_list(pHead, 4, &val) ){printf("删除成功,您删除的元素是: %d\n", val);}else{printf("删除失败!您删除的元素不存在!\n");}traverse_list(pHead);//int len = length_list(pHead);//printf("链表的长度是%d\n", len);//sort_list(pHead);//traverse_list(pHead);/* if ( is_empty(pHead) )printf("链表为空!\n");elseprintf("链表不空!\n");*/return 0;}PNODE create_list(void){int len; //用来存放有效节点的个数int val; //用来临时存放用户输入的结点的值//分配了一个不存放有效数据的头结点PNODE pHead = (PNODE)malloc(sizeof(NODE));if (NULL == pHead){printf("分配失败, 程序终止!\n");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("分配失败, 程序终止!\n");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;elsereturn false;}int length_list(PNODE pHead){PNODE p = pHead->pNext;int len = 0;while (NULL != p){++len;p = p->pNext;}return len;}void sort_list(PNODE pHead){int i, j, t;int len = length_list(pHead);PNODE p, q;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->data) //类似于数组中的: a[i] > a[j]{t = p->data;//类似于数组中的: t = a[i];p->data = q->data; //类似于数组中的: a[i] = a[j];q->data = t; //类似于数组中的: a[j] = t;}}}return;}//在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;}if (i>pos-1 || NULL==p)return false;PNODE pNew = (PNODE)malloc(sizeof(NODE));if (NULL == pNew){printf("动态分配内存失败!\n");exit(-1);}pNew->data = val;PNODE q = p->pNext;p->pNext = pNew;pNew->pNext = q;return true;}bool delete_list(PNODE pHead, int pos, int * pV al){int i = 0;PNODE p = pHead;while (NULL!=p->pNext && i<pos-1){p = p->pNext;++i;}if (i>pos-1 || NULL==p->pNext)return false;PNODE q = p->pNext;*pV al = q->data;//删除p节点后面的结点p->pNext = p->pNext->pNext;free(q);q = NULL;return true;}课下老师又加了注释的程序# include <stdio.h># include <malloc.h># include <stdlib.h>typedef 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 pHead, int pos, int val); //在pHead所指向链表的第pos个节点的前面插入一个新的结点,该节点的值是val,并且pos的值是从1开始bool delete_list(PNODE pHead, int pos, int * pV al); //删除链表第pos个节点,并将删除的结点的值存入pV al所指向的变量中, 并且pos的值是从1开始void sort_list(PNODE); //对链表进行排序int main(void){PNODE pHead = NULL; //等价于struct Node * pHead = NULL;int val;pHead = create_list(); //create_list()功能:创建一个非循环单链表,并将该链表的头结点的地址付给pHeadtraverse_list(pHead);//insert_list(pHead, -4, 33);if ( delete_list(pHead, 4, &val) ){printf("删除成功,您删除的元素是: %d\n", val);}else{printf("删除失败!您删除的元素不存在!\n");}traverse_list(pHead);//int len = length_list(pHead);//printf("链表的长度是%d\n", len);//sort_list(pHead);//traverse_list(pHead);/* if ( is_empty(pHead) )printf("链表为空!\n");elseprintf("链表不空!\n");*/return 0;}PNODE create_list(void){int len; //用来存放有效节点的个数int i;int val; //用来临时存放用户输入的结点的值//分配了一个不存放有效数据的头结点PNODE pHead = (PNODE)malloc(sizeof(NODE));if (NULL == pHead){printf("分配失败, 程序终止!\n");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("分配失败, 程序终止!\n");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;elsereturn false;}int length_list(PNODE pHead){PNODE p = pHead->pNext;int len = 0;while (NULL != p){++len;p = p->pNext;}return len;}void sort_list(PNODE pHead){int i, j, t;int len = length_list(pHead);PNODE p, q;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->data) //类似于数组中的: a[i] > a[j]{t = p->data;//类似于数组中的: t = a[i];p->data = q->data; //类似于数组中的: a[i] = a[j];q->data = t; //类似于数组中的: a[j] = t;}}}return;}//在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;}if (i>pos-1 || NULL==p)return false;//如果程序能执行到这一行说明p已经指向了第pos-1个结点,但第pos-1个节点是否存在无所谓//分配新的结点PNODE pNew = (PNODE)malloc(sizeof(NODE));if (NULL == pNew){printf("动态分配内存失败!\n");exit(-1);}pNew->data = val;//将新的结点存入p节点的后面PNODE q = p->pNext;p->pNext = pNew;pNew->pNext = q;return true;}bool delete_list(PNODE pHead, int pos, int * pV al){int i = 0;PNODE p = pHead;while (NULL!=p->pNext && i<pos-1){p = p->pNext;++i;}if (i>pos-1 || NULL==p->pNext)return false;//如果程序能执行到这一行说明p已经指向了第pos-1个结点,并且第pos个节点是存在的PNODE q = p->pNext; //q指向待删除的结点*pV al = q->data;//删除p节点后面的结点p->pNext = p->pNext->pNext;//释放q所指向的节点所占的内存free(q);q = NULL;return true;}{数据结构29~34笔记}# include <stdio.h># include <malloc.h>void f(int k){int m;double * q = (double *)malloc(200);}int main(void){int i = 10;int * p = (int *)malloc(100);return 0;}Stack# include <stdio.h># include <malloc.h># include <stdlib.h>typedef struct Node{int data;struct Node * pNext;}NODE, * PNODE;typedef struct Stack{PNODE pTop;PNODE pBottom;}STACK, * PSTACK; //PSTACK 等价于struct STACK *void init(PSTACK);void push(PSTACK, int );void traverse(PSTACK);bool pop(PSTACK, int *);void clear(PSTACK pS);int main(void){STACK S; //STACK 等价于struct Stackint val;init(&S); //目的是造出一个空栈push(&S, 1); //压栈push(&S, 2);push(&S, 3);push(&S, 4);push(&S, 5);push(&S, 6);traverse(&S); //遍历输出clear(&S);//traverse(&S); //遍历输出if ( pop(&S, &val) ){printf("出栈成功,出栈的元素是%d\n", val);}else{printf("出栈失败!\n");}traverse(&S); //遍历输出return 0;}void init(PSTACK pS){pS->pTop = (PNODE)malloc(sizeof(NODE));if (NULL == pS->pTop){printf("动态内存分配失败!\n");exit(-1);}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->Top不能改成pS->BottompS->pTop = pNew;return;}void traverse(PSTACK pS){PNODE p = pS->pTop;while (p != pS->pBottom){printf("%d ", p->data);p = p->pNext;}printf("\n");return;}bool empty(PSTACK pS){if (pS->pTop == pS->pBottom)return true;elsereturn false;}//把pS所指向的栈出栈一次,并把出栈的元素存入pV al形参所指向的变量中,如果出栈失败,返回false,否则返回truebool pop(PSTACK pS, int * pV al){if ( empty(pS) ) //pS本身存放的就是S的地址{return false;}else{PNODE r = pS->pTop;*pV al = r->data;pS->pTop = r->pNext;free(r);r = NULL;return true;}}//clear清空void clear(PSTACK pS){if (empty(pS)){return;}else{PNODE p = pS->pTop;PNODE q = NULL;while (p != pS->pBottom){q = p->pNext;free(p);p = q;}pS->pTop = pS->pBottom;}{数据结构45~53笔记}1+2+··100的和用递归实现# include <stdio.h>long sum(int n){if (1 == n)return 1;elsereturn n + sum(n-1); }int main(void){printf("%ld\n", sum(100));return 0;}不同函数间的相互调用# include <stdio.h>void f();void g();void k();void f(){printf("FFFF\n");g();printf("1111\n");}void g(){printf("GGGG\n");k();printf("2222\n");}void k(){printf("KKKK\n");}int main(void){f();return 0;}阶乘的递归实现# include <stdio.h>//假定n的值是1或大于1的值long f(long n){if (1 == n)return 1;elsereturn f(n-1) * n;}int main(void){printf("%ld\n", f(100));return 0;}结成的循环使用# include <stdio.h>int main(void){int val;int i, mult=1;printf("请输入一个数字: ");printf("val = ");scanf("%d", &val);for (i=1; i<=val; ++i)mult = mult * i;printf("%d的阶乘是:%d\n", val, mult);return 0;}循环队列# include <stdio.h># include <malloc.h>typedef struct Queue{int * pBase;int front;int rear;}QUEUE;void init(QUEUE *);bool en_queue(QUEUE *, int val); //入队void traverse_queue(QUEUE *);bool full_queue(QUEUE *);bool out_queue(QUEUE *, int *);bool emput_queue(QUEUE *);int main(void){QUEUE Q;int val;init(&Q);en_queue(&Q, 1);en_queue(&Q, 2);en_queue(&Q, 3);en_queue(&Q, 4);en_queue(&Q, 5);en_queue(&Q, 6);en_queue(&Q, 7);en_queue(&Q, 8);traverse_queue(&Q);if ( out_queue(&Q, &val) ){printf("出队成功,队列出队的元素是: %d\n", val);}else{printf("出队失败!\n");}traverse_queue(&Q);return 0;}void init(QUEUE *pQ){pQ->pBase = (int *)malloc(sizeof(int) * 6);pQ->front = 0;pQ->rear = 0;}bool full_queue(QUEUE * pQ){if ( (pQ->rear + 1) % 6 == pQ->front )return true;elsereturn false;}bool en_queue(QUEUE * pQ, int val){if ( full_queue(pQ) ){return false;}else{pQ->pBase[pQ->rear] = val;pQ->rear = (pQ->rear+1) % 6;return true;}}void traverse_queue(QUEUE * pQ){int i = pQ->front;while (i != pQ->rear){printf("%d ", pQ->pBase[i]);i = (i+1) % 6;}printf("\n");return;}bool emput_queue(QUEUE * pQ){if ( pQ->front == pQ->rear )return true;elsereturn false;}bool out_queue(QUEUE * pQ, int * pV al) {if ( emput_queue(pQ) ){return false;}else{*pV al = pQ->pBase[pQ->front];pQ->front = (pQ->front+1) % 6;return true;}}自己调用自己# include <stdio.h>void f(int n){if (n == 1)printf("哈哈\n");elsef(n-1);}int main(void){f(3);return 0;{数据结构54~58笔记}A函数调用B函数举例# include <stdio.h>int f(int n){int i, j;n += 2; // n = n + 2;return n;}int main(void){int val;val = f(5);printf("val = %d\n", val);return 0;}A函数调用b函数2# include <stdio.h>int g(int);int f(int n){if (n < 3)printf("哈哈\n");elsen = f(n-1);return n;}int g(int m){m = m*2;return m;}int main(void){int val;val = f(5);return 0;}递归的值可以递增,但处理的规模在递减举例# include <stdio.h>int g(int);int f(int n){if (n > 7)printf("哈哈\n");elsen = f(n+1);return n;}int g(int m){m = m*2;return m;}int main(void){int val;val = f(5);return 0;}汉诺塔# include <stdio.h>void hannuota(int n, char A, char B, char C){/*如果是1个盘子直接将A柱子上的盘子从A移到C否则先将A柱子上的n-1个盘子借助C移到B直接将A柱子上的盘子从A移到C最后将B柱子上的n-1个盘子借助A移到C*/if (1 == n){printf("将编号为%d的盘子直接从%c柱子移到%c柱子\n", n, A, C);}else{hannuota(n-1, A, C, B);printf("将编号为%d的盘子直接从%c柱子移到%c柱子\n", n, A, C);hannuota(n-1, B, A, C);}}int main(void){char ch1 = 'A';char ch2 = 'B';char ch3 = 'C';int n;printf("请输入要移动盘子的个数: ");scanf("%d", &n);hannuota(n, 'A', 'B', 'C');return 0;}间接调用自己举例# include <stdio.h>void f(int n){g(n);}void g(int m){f(m);}int main(void){return 0;}{数据结构66~73笔记}详见pdf{数据结构74~78笔记}快速排序# include <stdio.h>int FindPos(int * a, int low, int high);void QuickSort(int * a, int low, int high);int main(void){int a[6] = {-2, 1, 0, -985, 4, -93};int i;QuickSort(a, 0, 5); //第二个参数表示第一个元素的下标第三个参数表示最后一个元素的下标for (i=0; i<6; ++i)printf("%d ", a[i]);printf("\n");return 0;}void QuickSort(int * a, int low, int high){int pos;if (low < high){pos = FindPos(a, low, high);QuickSort(a, low, pos-1);QuickSort(a, pos+1, high);}}int FindPos(int * a, int low, int high){int val = a[low];while (low < high){while (low<high && a[high]>=val)--high;a[low] = a[high];while (low<high && a[low]<=val)++low;a[high] = a[low];}//终止while循环之后low和high一定是相等的a[low] = val;return high; //high可以改为low, 但不能改为val 也不能改为a[low] 也不能改为a[high] }快速排序试数链式二叉树# include <stdio.h># include <malloc.h>struct BTNode{char data;struct BTNode * pLchild; //p是指针L是左child是孩子struct BTNode * pRchild;};void PostTraverseBTree(struct BTNode * pT);struct BTNode * CreateBTree(void);void PreTraverseBTree(struct BTNode * pT);void InTraverseBTree(struct BTNode * pT);int main(void){struct BTNode * pT = CreateBTree();// PreTraverseBTree(pT);// InTraverseBTree(pT);PostTraverseBTree(pT);return 0;}void PostTraverseBTree(struct BTNode * pT){if (NULL != pT){if (NULL != pT->pLchild){PostTraverseBTree(pT->pLchild);}if (NULL != pT->pRchild){PostTraverseBTree(pT->pRchild);//pT->pLchild可以代表整个左子树}printf("%c\n", pT->data);}}void InTraverseBTree(struct BTNode * pT){if (NULL != pT){if (NULL != pT->pLchild){InTraverseBTree(pT->pLchild);}printf("%c\n", pT->data);if (NULL != pT->pRchild){InTraverseBTree(pT->pRchild);//pT->pLchild可以代表整个左子树}}}void PreTraverseBTree(struct BTNode * pT){if (NULL != pT){printf("%c\n", pT->data);if (NULL != pT->pLchild){PreTraverseBTree(pT->pLchild);}if (NULL != pT->pRchild){PreTraverseBTree(pT->pRchild);//pT->pLchild可以代表整个左子树}}/*伪算法先访问根节点再先序访问左子树再先序访问右子树*/}struct BTNode * CreateBTree(void){struct BTNode * pA = (struct BTNode *)malloc(sizeof(struct BTNode));struct BTNode * pB = (struct BTNode *)malloc(sizeof(struct BTNode));struct BTNode * pC = (struct BTNode *)malloc(sizeof(struct BTNode));struct BTNode * pD = (struct BTNode *)malloc(sizeof(struct BTNode));struct BTNode * pE = (struct BTNode *)malloc(sizeof(struct BTNode));pA->data = 'A';pB->data = 'B';pC->data = 'C';pD->data = 'D';pE->data = 'E';pA->pLchild = pB;pA->pRchild = pC;pB->pLchild = pB->pRchild = NULL;pC->pLchild = pD;pC->pRchild = NULL;pD->pLchild = NULL;pD->pRchild = pE;pE->pLchild = pE->pRchild = NULL;return pA;}。
C语言学习大纲 郝斌
C语言概述:1、为什么学习C语言1). C的起源和发展2).C的特点优点代码量小速度快功能强大缺点危险性高开发周期长可移植性不强3).c的应用领域主要是系统领域4).c的重要性2、怎样学习C语言3、学习的目标了解程序语言及发展历史熟练掌握c语言的语法规则掌握简单的算法理解面向过程的思想,这非常有助于将来对面向对象思想的学习能看懂程序会调试程序掌握将大问题转化为一系列小问题来求解的思想为学习c++、数据结构、c#、java打下良好的基础4、常见的学习问题1、学习java为什么建议先学习C语言2、没学过计算机专业的课程能够学懂C语言3、英语和数学不好能学好C吗32个关键词:(有系统定义,不能重做其他定义)auto break case char constcontinue default do double elseenum extern float for gotoif int long register returnshort signed sizeof static structswitch typedef unsigned unsignedunion void volatile while5、课程规划c语言简介第一讲、基本编程知识第二讲、数据类型第三讲、运算符和表达式第四讲、流程控制(所有语言都一样的)第五讲、函数(体现出面向过程和面向对象的区别)第六讲、数组第七讲、指针(c语言的灵魂)第八讲、变量的作用域和存储方式第九讲、扩展数据类型第十讲、专题:字符串的处理进制转换补码动态内存分配(java、数据结构必学)综合应用:链表的使用6、举例子:一元二次方程# include <># include <>int main (void){01组成的代码可以表示数据也可以表示指令2. 如果01组成的代码表示的是数据的话,那么同样的01代码组合以不同的输出格式输出就会有不同的输出结果scanf () ----Java中已经没有了两种用法:用法一: scanf ("输入控制符",输入参数);功能:将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入已输入参数的值为地址的变量中。
郝斌数据结构自学笔记--知识点+程序源代码
2)离散存储[链表]
线性结构的两种常见应用之一栈
线性结构的两种常见应用之二队列
专题:递归
double arr[3]={1.1,2.2,3.3};
double *q;
q=&arr[0];
printf(“%p\n”,q);//%p实际就是以十六进制输出
q=&arr[1];
q=printf(“%p\n”,q);//p,q相差8
无论指针指向的变量占多少个字节,指针变量统一都只占4个字节
7_如何通过函数修改实参的值
void ShowStudent(struct Student *);
int main(void)
{
struct Student *ps;
ps=CreatStudent();
ShowStudent(ps);
return 0;
}
struct Student * CreatStudent(void)
{
struct Student *P=(struct Student *)malloc(sizeof(struct Student));
NOTE:1)指针变量也是变量,普通变量前不能加*,常亮和表达式前不能加&。
2)局部变量只在本函数内部使用。
如何通过被调函数修改主调函数中普通变量的值。
1)实参为相关变量的地址;
2)形参为以该变量的类型为类型的指针变量;
3)在被调函数中通过*形参变量名的形式的形式就可以修改主函数。
CASE 1
#include<stdio.h>
数据结构=个体的存储+个体的关系存储
算法=对存储数据的操作
2_衡量算法的标准
郝斌C语言详细笔记(附源码)
郝斌老师的C语言:课堂讲解全程动手敲代码,讲解细致,对于重要知识点的讲解不厌其烦,是一个难得的C语言入门教程。
在这里对老师的辛勤付出表示感谢。
郝斌c语言视频教程·概述:课程计划为什么学习c语言:Fortran语言主要用于科学计算,在第三代语言中,以1980年为分水岭,分为结构化和面向对象语言。
Basic语言是vb的前生,pascal语言一般是用于教学。
C语言是最重要的,其他的语言一般很少用了。
结构化的代表语言是c语言。
结构化语言的数据和操作是分离的,导致在写大项目的时候,会出现各种各样莫名其妙的问题。
【在面向对象的语言中c++是最复杂的语言。
由于c++语言太复杂,sun公司对c++进行了改装,产生了java语言。
而c#是由微软开发的,和java相似,几乎一模一样。
在高级语言的执行速度上,c是最快的,c++其次,而java 和c#是最后的。
Java和c#流行,主要的一个原因是可以跨平台。
C语言的发展和过程:C语言的特点:·优点:代码量小,速度快,功能强大。
·缺点:危险性高,开发周期长,可移植性弱。
危险性高:写同一个程序,在java中会报错,而在c中不会报错,为什么呢,因为c认为程序你想怎么写就怎么写,c语言认为你写的程序不是很离谱,他都认为你写的这个程序有特殊的含义。
可以直接通过,而java 则不可以。
开发周期长:c语言是面向过程的语言,面向过程的语言的特点就是在开发大项目的时候,很容易崩溃,好比盖大楼,C语言还要造大量的砖块、钢筋等结构原材料,而C++ C# JAVA则进行了一定的继承封装等操作,相当于原材料直接给你,你只需要用它盖楼即可。
\现在市场上的语言分三块C/c++:单纯的学习c是什么都做不了的。
JavaC#可移植性不强:这是针对java来说的,因为java的可移植性太强了,所以就感觉说c的可移植性不强。
金山公司最主要是靠wps办公软件来发展的。
Wps是c 语言开发的,其安装包比Office少了10多倍。
数据结构学习笔记(郝斌老师)
(这个程序在语法上并没有问题,但是,操作系统只允许程序操作已经开辟了的内存空间, 开辟了的存储空间就属于该程序的天地,不允许程序对未开辟的不属于这个程序的天地进 行操作,例如读写操作,或者说其他操作。操作系统会检验出这个程序存在超越权限的代 码,所以程序跑起来时会被操作系统报错,然后被终止。例如,具体来说就是,int *q,就 为 q 变量开辟了一块存储单元, 这一块存储空间就属于这个程序的天地, 可以对其进行操作, 例如进行同类型变量的赋值等操作、p=q、,但是,printf(“%d\n”,*q),因为 q 变量存储的是 一个不属于该程序天地的一块存储单元的地址,*p 就是对这这块区域进行取值运算,就属 于对不属于这个程序天地的进行读的操作,这样的操作是不被操作系统允许的,)
指针的变量值是人赋予的那些数据,其变化范围就是数学上所定义的那个范围。 语法程序举例 1: # include <stdio.h> int main(void) { int * p; //p 是变量的名字, int * 表示 p 变量存放的是 int 类型变量的地址 int i = 3; p = &i; //OK
printf("%#X\n", &a[0]); printf("%#X\n", a); return 0; } /* 在 Vc++6.0 中的输出结果是: -------------0X12FF6C 0X12FF6C Press any key to continue -------------总结: 一维数组名 一维数组名是个指针常量,常量意味着,其值不可以被改变 它存放的是一维数组第一个元素的地址 */ 指针变量,变量,这两种变量的“变”,一定要好好理解,它的变化范围是什么,变化 对象是什么,一定要搞清楚。 指针变量也是变量, 它与变量的区别在于其存放的东西不一样, 这就意味着变化的对象 不一样;以及变化的范围不同。 指针变量存放的是地址值 (为什么要经常用字母 p 来表示一个指针变量, 就是因为它里 面存放的是地址值,是位置信息,英文单词 position 的首字母为 p),地址值是变量在定义 时计算机赋给变量的一个计算机识别的标识,它的值是计算机编好的一系列的编号。所以, 指针变量的变化范围就是那些所有的地址值编号,一般来说就是以 16 进制表示的从 0 开始 的一系列的数。
(完整word版)C语言学习大纲郝斌(讲解)
(完整word版)C语言学习大纲郝斌(讲解)C语言概述:1、为什么学习C语言1)。
C的起源和发展2).C的特点优点代码量小速度快功能强大缺点危险性高开发周期长可移植性不强3)。
c的应用领域主要是系统领域4)。
c的重要性2、怎样学习C语言3、学习的目标了解程序语言及发展历史熟练掌握c语言的语法规则掌握简单的算法理解面向过程的思想,这非常有助于将来对面向对象思想的学习能看懂程序会调试程序掌握将大问题转化为一系列小问题来求解的思想为学习c++、数据结构、c#、java打下良好的基础4、常见的学习问题1、学习java为什么建议先学习C语言2、没学过计算机专业的课程能够学懂C语言3、英语和数学不好能学好C吗32个关键词:(有系统定义,不能重做其他定义)auto break case char constcontinue default do double elseenum extern float for gotoif int long register returnshort signed sizeof static structswitch typedef unsigned unsignedunion void volatile while5、课程规划c语言简介第一讲、基本编程知识第二讲、数据类型第三讲、运算符和表达式第四讲、流程控制(所有语言都一样的)第五讲、函数(体现出面向过程和面向对象的区别)第六讲、数组第七讲、指针(c语言的灵魂)第八讲、变量的作用域和存储方式第九讲、扩展数据类型第十讲、专题:字符串的处理进制转换补码动态内存分配(java、数据结构必学)综合应用:链表的使用6、举例子:一元二次方程# include <stdio。
h〉# include 〈math.h〉int main (void){//把三个系数保存到计算机中int a=1; //=不表示相等,表示赋值int b=2;int c=3;double delta; //delta存放的是b*b—4*a*cdouble x1; //存放一元二次方程的其中一个解double x2; //存放一元二次方程的其中一个解(完整word版)C语言学习大纲郝斌(讲解) delta= b*b — 4*a*c;if(delta〉0){x1 = (-b + sqrt(delta)) / (2*a)x2 = (-b - sqrt(delta)) / (2*a)printf(”该一元二次方程有两个解,x1=%f,x2=%f\n”,x1,x2);}else if (delta==0){x1 =(—b)/(2*a);x1=x2; //右边赋给左边printf(”该一元二次方程有一个唯一解,x1 = x2=%f\n",x1);}else{printf("无解\n");}}Helloword程序举例# include 〈stdio。
郝斌数据结构学习笔记1
郝斌c语言学习笔记这篇文本我写过后做很多次修改,虽然感觉还是无法做到最合理的解释,但也希望能对想真正理解c语言的人有所帮助,这里我只写了一部分,往后我会定时上传。
正在看郝斌的数据结构,看到了指针,觉得讲的很不错的,int *p;定义一个整形的指针变量int i=10;定义一个整形变量i=10;p=&i;将i取地址给p(也叫做p指向i)我们叫做p指向i,p中装载的是i的地址,而*p与i是属于一体的,也就是说此时无论i变为何值*p也就是为何值。
指针与一维数组列如:int a[5]={1,2,3,4,5};我们可以写成a[3]=*(a+3);那么为什么a[3]这个元素可以等价于*(a+3)呢?答案:因为a所指向的是这个数组的第一个地址,这个是需要记住的,也就是说内部库这么定义的,*a是一个指针变量,而指针a中也就是第一个元素的地址,那么(a+3)就说明了一维数组的第一个元素的地址向后推移了3位,也就是数组的第四位a[3]的地址,此时a[3]的地址也就是指针,所以*(a+3)对应的是a[3]的数值4,当然也可以有另一种写法*a+3,*a代表的是第一个元素的数值也就是a[0]=1;1+3=4;所以也可以代表a[3]的值。
以上是看了郝斌数据结构指针与一维数组的理解。
指针与内存以及指向对象的类型关系?答案:一般指针占用四个字节,那么指针与数组类型的关系?列如:double arry[3]={1.1,2.2,3.3}这是一个double类型的数组每个元素占有8个字节,我们在定义两个指针:Int *p; int *q;p=arry[0];q=arry[1];我们把数组的第一个与低二个元素给指针pq那么p,q内部装载的是什么,可知p,q为指针所以存储应该是元素的地址,因为double类型的数组是八个字节,但是指针只存储这个元素的第一个字节,因为一个字节也就是一个地址,而指针只存储一个元素的首地址所以只存储一个字节。
C语言数据结构之连续存储数组的算法
C语⾔数据结构之连续存储数组的算法数据结构之数组定义及基本操作 数据结构中最基本的⼀个结构就是线性结构,⽽线性结构⼜分为连续存储结构和离散存储结构。
所谓的连续存储结构其实就是数组。
数组本质其实也是数据的⼀种存储⽅式,既然有了数据的存储,就会涉及到如何对数据进⾏寻址的问题。
⾸先,先说⼀下在数组中数据是如何存储的,在内存中,数组中的数据是以⼀组连续的数据集合的形式存在于内存中。
当我们访问存在于内存中的数组时,我们应该找到其在内存中的地址,当我们找到数据的地址后我们就可以找到对应的数据。
了解了以上知识后,我们就可以进⾏数组的设计了(我们就可以设计⾃⼰的数组供别⼈去使⽤了,哈哈)。
了解了以上知识后,第⼀个问题就来了,如何才能找到数据在内存中的地址?这个问题其实很简单,因为数组在内存中是⼀组连续的数据集合,所以我们只要知道数组⾸地址,然后通过对应字节长度的加减就可以找到对应字节数的数据,有了这些就可以定义出我们的数组,但是,作为⼀个合理的数组,还应该有数组长度的标志len和数组有效元素的标志cnt。
由此给出对数组的定义(本例中采⽤结构体,对结构体不了解的朋友可以去查⼀下)struct Arr{int *pBase; //存储的是数组的第⼀个元素的地址int len; //数组所能容纳的最⼤元素的个数int cnt; //数组有效元素的个数};上述代码定义了⼀个struct Arr的结构体,这个结构体就是⼀个数组,其中有存储数组元素中⾸地址的成员,有存储数组长度和数组有效元素个数的成员。
有了对结构体的定义之后,就应该涉及到对数组的基本操作,包括数组的初始化,判断数组是否为空,对数组进⾏显⽰,判断数组是否已满,对数组的最后追加⼀个元素,对数组元素的插⼊。
其中,主要的算法就是对数组元素的插⼊,插⼊算法的核⼼就是⾸先应该先将被插⼊及插⼊位置之后的元素后移,然后将空出来的位置插⼊我们要插⼊的元素。
⼀下给出c语⾔的实现:/*数组初始化函数初始化仅仅是给出⼀个具有⼀定长度的数组,但是数组中没有有效值*/void init_arr(struct Arr * pArr,int len){pArr->pBase=(int *)malloc(sizeof(int)*len);if(NULL==pArr->pBase){printf("动态内存分配失败");exit(-1); //终⽌整个程序}else{pArr->len=len;pArr->cnt=0;}}/*判断数组是否为空的函数*/int is_empty(struct Arr * pArr){if(pArr->cnt==0){return 0; //0代表true}else{return 1; //1代表false}}/*数组输出显⽰函数在进⾏数组输出时,⾸先应该判断数组是否为空*/void show_arr(struct Arr * pArr){if(is_empty(pArr)==0){printf("当前数组为空!");}else{int i;for(i=0; i<pArr->cnt; ++i){printf("%d ",pArr->pBase[i]);}printf("\n");}}/*判断数组是否已满的函数*/int is_full(struct Arr * pArr){if(pArr->cnt==pArr->len){return 0; //0代表true,表⽰已满}else{return 1; //1代表false,表⽰未满}}/*在数组的最后追加⼀个元素在追加数组元素前要判断当前数组是否已满,已满时不允许追加新的元素*/int append_arr(struct Arr *pArr,int val){if(is_full(pArr)==0){return 0;}else{pArr->pBase[pArr->cnt]=val;pArr->cnt++;return 1;}}/*在数组的指定位置插⼊元素插⼊算法:⾸先将被插⼊位置的元素全部后移,然后再将空出来的位置插⼊。
郝斌老师数据结构大纲word版
一、连续存储[数组]
1.什么叫做数组
元素类型相同,大小相等
2.数组的优缺点(相对于链表)
优点:存取速度快
缺点:实现必须知道数组的长度
需要大块连续的内存块
插入和删除元素很慢
空间通常是有限制的
二、离散存储[链表]
1.定义
N 个结点离散分配
彼此通过指针相连
每个结点只有一个前驱结点,每个结点只有一个后续结点
front 代表的是队列的第一个元素 rear 代表的是队列的最后一个有效元素的下一个元素 ③队列空
front 和 rear 的值相等,但不一定是零 ④循环队列入队伪算法讲解(在尾部入队)
第一步:将值存入 rear 所指向的位置 第二步:rear = (rear + 1)%数组的长度 ⑤循环队列出队伪算法讲解(在头部出队)
首结点没有前驱结点,尾结点没有后续结点
专业术语:
首结点:第一个存放有效数据的结点
尾结点:最有一个存放有效数据的结点
头结点:头结点的数据类型和首结点的类型是一样的
首结点之前的结点
头结点并不存放有效数据
-4-
数据结构资料
加头结点的目的是为了方便对链表的操作 头指针:指向头结点的指针变量 尾指针:指向尾结点的指针变量 确定一个链表需要几个参数: (如果希望通过一个函数来对链表进行处理,我们至少需要接受链表的那些参 数) 一个参数,即头指针,因为我们通过头指针可以推算出链表的其它所有的信息 2.分类 单链表 双链表:每一个结点有两个指针域
return 0; }
scanf ("%d",&val); printf("%d 的阶乘是%ld", val, mult(val));
我写的郝斌 C语言笔记
变量按存储方式分:静态变量、自动变量、寄存器(cpu内存数据的硬件设备)变量
# include <stdio.h>
3)函数返回值的类型也称为函数的类型,如果与return 表达式;的类型发生冲突,以 函数返回值的类型为准。
例如: int f()
{
return 10.5;//因为函数的返回值类型是int,所以最终f函数返回的是10,而不是10.5。
}
109. return和break的区别
{
printf("%-5d",a[i][j]);//-表示左对齐,5表示每个元素占5个光标
}
printf("\n");
}
对二维数组排序
求每一行的最大值
判断矩阵是否对称
矩阵的相乘
103.是否存在多维数组
不存在,因为内存是线性一维的,n维数组可以当做 每个元素是n-1维数组的 一维数组。
函数是一个工具,它是为了解决大量类似问题而设计的,函数可以当做一个黑匣子。
#include <stdio.h>
int f(void) // 括号里的void表示该函数不能接受数据,int表示函数返回值是int类型的数据
{
return 10; // 向被调函数返回10
}
void g(void)
for(i=0;i<5;+.二维数组的使用
如何看懂一个程序(郝斌老师)
如何看懂一个程序(郝斌老师)
郝斌老师方法
如何看懂一个程序,分三步:
1.流程
2.每个语句的功能
3.试数
如何学习一些需要算法的程序【如何掌握一个程序】:
1.尝试自己去编程解决它
2.但要意识到大部分人都是自己无法解决的,如果解决不了,这时不要气馁,如果十五分钟还想不出来,此时我建议您就可以看答案了。
3.如果解决不了,就看答案
4.关键是把答案看懂,这个要花很大的精力,也是我们学习的重点。
5.看懂一个程序要分三步:流程、每个语句的功能、试数。
6.看懂之后尝试自己去修改程序,并且知道修改之后程序的不同输出结果的含义,不建议看懂程序之后就立即自己敲程序。
7.照着答案去敲,调试错误。
8.不看答案,自己独立把答案敲出来。
9.如果程序实在无法彻底理解,就把它背会,无法彻底理解的程序很少很少(几乎没有)。
上面是偶然看到一篇文章了解到的,虽然没听过郝老师的课,但是听说郝老师是随堂写代码,不是一味的念PPT,讲解很深入,所以对于初学者很不错的选择。
然后上面这些方法大多也是我不知不觉再用的,我也没有看谁的固定的方法,自己走出来的觉得最优的路才是好的,上面这只是一个参考。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
# include<stdio.h>
# include<malloc.h>
# include<stdlib.h>
//定义了一个数据类型,该数据类型的名字叫做struct Arr.该数据类型含有三个成员
struct Arr
{
int *pBase; //存储的是数字的第一个原素的地址
int len; //数组所能容纳的最大元素的个数
int cnt; //当前数组有效元素的个数
//int increment; //自动增长因子allocate()函数要用到};
void init_arr(struct Arr *pArr,int length);
//初始化,如果调用该函数则第一个元素就会指向一个有效的数组
bool append_arr(struct Arr *pArr, int val);
//追加
bool insert_arr(struct Arr *pArr, int pos, int val);
//插入!pos下标的值要从1开始
bool delete_arr(struct Arr *pArr, int pos, int *pVal);
//删除数组元素必须用指针来接收
bool is_empty(struct Arr *pArr);
bool is_full(struct Arr *pArr);
void sort_arr(struct Arr *pArr);
//先介绍冒泡排序
void show_arr(struct Arr *pArr);
void inversion_arr(struct Arr *pArr);
//倒置元素
int main(void)
{
struct Arr arr; //还没有被初始化,pbase中并没有一个有效的地址,里面是一个垃圾值
int val;
init_arr(&arr, 6); // init_arr(arr);是错误的无法改变数组的长度//并不需要返回值
printf("该数组的长度为%d\n", arr.len);
append_arr(&arr,254);
append_arr(&arr,23);
append_arr(&arr,5);
append_arr(&arr,6);
append_arr(&arr,0);
insert_arr( &arr,1, 77 );
printf("插入元素后的数组是\n");
show_arr(&arr);
printf("\n");
/*if (delete_arr(&arr, 1, &val))
{
printf("删除成功!\n");
printf("您删除的元素是:%d\n",val);
}
else
printf("删除失败\n");
*/
inversion_arr(&arr);
printf("倒置元素后的数组是\n");
show_arr(&arr);
printf("\n");
sort_arr( &arr);
printf("排序元素后的数组是\n");
show_arr(&arr);
printf("\n");
return 0;
}
void init_arr( struct Arr *pArr ,int length)
{
//(*pArr).len = 99; 可以初始化数组的长度为99 pArr->pBase = (int *)malloc(sizeof(int) * length);
if( NULL == pArr->pBase)// NULL要大写
{
printf("动态内存分配失败!\n");
exit(-1);
}
else
{
pArr->len = length;
pArr->cnt = 0;
return;
}
bool is_empty( struct Arr *pArr ) //判断这个数组是否为空{
if ( 0 == pArr->cnt)
return true;
else
return false;
}
void show_arr( struct Arr * pArr ) //pArr已经是arr的地址了{
if ( is_empty( pArr) )
printf("该数组为空\n");
else
{
for (int i = 0; i<pArr->cnt; ++i)
printf("%d ", pArr->pBase[i]); // int *类型printf("\n");
}
bool append_arr(struct Arr *pArr, int val) // 在最后追加一个元素
{
if(is_full(pArr))
return false;
else //不满的时候追加
{
pArr->pBase[pArr->cnt] = val;
(pArr->cnt)++;
return true;
}
}
bool is_full(struct Arr *pArr)
{if ( pArr->len == pArr->cnt)
return true;
else
return false;
}
bool insert_arr( struct Arr *pArr, int pos, int val ) {
int i;
if(is_full(pArr))
{
printf("数组已满无法插入\n");
return false;
}
if (pos<1 || pos >pArr-> cnt+1)
{
printf("不在可以插入的范围之内\n");
return false;
}
for( i = pArr->len - 1; i>=pos-1; --i)
{
pArr->pBase[i] = pArr->pBase[i-1];
}
pArr->pBase[pos-1] = val;
(pArr->cnt)++;
return true;
}
bool delete_arr(struct Arr *pArr, int pos, int *pVal) {
int i;
if(is_empty(pArr) )
return false;
if(pos<1 || pos>pArr->cnt)
return false;
*pVal = pArr->pBase[pos-1];
for(i=pos; i<pArr->cnt; ++i)
{
pArr->pBase[i-1] = pArr->pBase[i];
}
(pArr->cnt)--;
return true;
}
void inversion_arr(struct Arr *pArr)
{
int i = 0;
int j = pArr->cnt-1;
int t;
while(i < j)
{
t = pArr->pBase[i];
pArr->pBase[i] = pArr->pBase[j];
pArr->pBase[j] = t;
++i;
--j;
}
}
void sort_arr( struct Arr *pArr)
{
int i, j, t;
for(i = 0; i<pArr->cnt ; ++i)
{
for(j = i +1; j<pArr->cnt; ++j)
{
if(pArr->pBase[i] > pArr->pBase[j])
{
t = pArr->pBase[i];
pArr->pBase[i] = pArr->pBase[j];
pArr->pBase[j] = t;
}
}
}
}。