数据结构(二)
2016-02-21 21:43
357 查看
数据结构-线性结构:数组、链表
数组的原理,底层实现。在c语言中,有int arr[],java有String arr[],ArrayList。但他们在底层是如何实现的,比如ArrayList的add,remove函数的底层c代码,下面是完整的程序:
![](http://img.blog.csdn.net/20160221213955589?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
函数的功能:
初始化函数:void init_arr(struct Arr * pArr,int length);初始化的作用是向系统请求内存分配给结构体指针,如果没有初始化,结构体指针保存的是垃圾数字。
排序函数:void sort_arr(struct Arr * pArr);是用冒泡法,每一次比较将大的往后移。
ArrayList的方法在底层差不多就是这样了。
在定义结构体时,为了方便,可以使用typedef,PSTU代表struct Student *,STU 代表struct Student
例如:
![](http://img.blog.csdn.net/20160221214058661?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
链表:链表是数据结构的基础,树和图的实现基本靠链表实现
定义:
n个结点离散分配
彼此通过指针相连
每个结点只有一个前驱结点,每个结点只有一个后续结点
首结点没有前驱结点,尾结点没有后续结点
专业术语:
首结点
第一个有效结点
尾结点
最后一个有效结点
头结点
第一个有效结点前面的结点
头结点并不存放有效数据
加头结点的目的是方便对链表的操作
头指针
指向首结点的指针变量
尾指针
指向尾结点的指针变量
确定一个链表只需要一个参数:头指针
![](http://img.blog.csdn.net/20160221214150756?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
链表的分类:
单链表
双链表:每一个结点都有一个指针域
循环链表:能通过任何一个结点找到所有的结点
非循环链表
结点插入原理:将q结点插在p结点和r结点中间
1.r=p->pNext;p->pNext=q->pNext;q->pNext=r;
2.q->pNext=p->pNext;p->pNext=q;
数组的原理,底层实现。在c语言中,有int arr[],java有String arr[],ArrayList。但他们在底层是如何实现的,比如ArrayList的add,remove函数的底层c代码,下面是完整的程序:
#include <stdio.h> #include <malloc.h> #include <stdlib.h> struct 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);//插入 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 show_arr(struct Arr * pArr);//显示 void inversion_arr(struct Arr * pArr);//倒序 int main(void) { struct Arr arr; int pval; printf("原先数组\n"); init_arr(&arr,6); //show_arr(&arr); append_arr(&arr,1); append_arr(&arr,2); append_arr(&arr,3); append_arr(&arr,4); append_arr(&arr,5); show_arr(&arr); printf("删除后数组\n"); if(delete_arr(&arr,3,&pval)) { printf("删除了 %d\n",pval); } show_arr(&arr); printf("倒序后数组\n"); inversion_arr(&arr); show_arr(&arr); printf("排序后数组\n"); sort_arr(&arr); show_arr(&arr); 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; } } bool is_empty(struct Arr * pArr) { if(0 == pArr->cnt) { return true; } else { return false; } } bool is_full(struct Arr * pArr) { if(pArr->len == pArr->cnt) { return true; } else { return 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]); } printf("\n"); } } bool append_arr(struct Arr * pArr,int val) { if(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->len) { return false; } for(i=pArr->cnt-1;i>pos-1;i++) { pArr->pBase[i+1]=pArr->pBase[i]; } pArr->pBase[pos-1]=val; 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--; } 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; } } } return; }
函数的功能:
初始化函数:void init_arr(struct Arr * pArr,int length);初始化的作用是向系统请求内存分配给结构体指针,如果没有初始化,结构体指针保存的是垃圾数字。
排序函数:void sort_arr(struct Arr * pArr);是用冒泡法,每一次比较将大的往后移。
ArrayList的方法在底层差不多就是这样了。
在定义结构体时,为了方便,可以使用typedef,PSTU代表struct Student *,STU 代表struct Student
例如:
链表:链表是数据结构的基础,树和图的实现基本靠链表实现
定义:
n个结点离散分配
彼此通过指针相连
每个结点只有一个前驱结点,每个结点只有一个后续结点
首结点没有前驱结点,尾结点没有后续结点
专业术语:
首结点
第一个有效结点
尾结点
最后一个有效结点
头结点
第一个有效结点前面的结点
头结点并不存放有效数据
加头结点的目的是方便对链表的操作
头指针
指向首结点的指针变量
尾指针
指向尾结点的指针变量
确定一个链表只需要一个参数:头指针
链表的分类:
单链表
双链表:每一个结点都有一个指针域
循环链表:能通过任何一个结点找到所有的结点
非循环链表
结点插入原理:将q结点插在p结点和r结点中间
1.r=p->pNext;p->pNext=q->pNext;q->pNext=r;
2.q->pNext=p->pNext;p->pNext=q;
相关文章推荐
- 数据结构(一)
- hdu 3577(线段树区间更新)
- 数据结构: 数组与字符串问题
- 跟我学数据结构之树
- 跟我学数据结构之数组和广义表
- 《数据结构与算法分析(c描述)》——二叉搜索树实现
- 树和递归(一)[leetcode]Balanced Binary Tree
- opencv基本数据结构
- 数据结构(9)--链队列的定义以及相关操作的实现
- 数据结构(8)--栈的应用之行编辑程序、括号匹配检验、数制转换、hanio塔问题
- 最小生成树-普里姆方法(Prim)
- 大学时数据结构课上写的排序算法
- 数据结构基础之图的遍历
- 《数据结构与算法分析(c 描述)》—— 第四章笔记
- 数据结构基础之图的存储结构
- 数据结构(7)—栈的应用之迷宫求解
- 《数据结构》进行曲(之一)---线性表的顺序表示
- 数据结构之回溯算法
- 数据结构常用树的基本总结
- hihocoder #1078 : 线段树的区间修改