数据结构(c)——线性表:顺序表和链式表
2016-04-16 15:26
274 查看
因为已经大三下学期,准备暑假找实习,以前学得渣,这段时间恶补下基础!!数据结构和算法搞起
线性表包括顺序存储和链式存储两种形式。
定义结构体,内部定义指针作为线性表的基址,动态分配后就可以用下标访问,跟数组一样,数组a[10],a是指向第一个元素的指针,
声明一个插入的函数,比较有代表性,其他操作就省略了。。
第一个参数传入SqList类型的引用,在函数操作中需修改变量值!
主函数首先声明SqList类型的变量,动态分配100个char型变量的内存空间,返回基址给elem,接着赋值length,listsize,初始化搞定。
![](http://img.blog.csdn.net/20160416212805216?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
顺序表各元素在物理上也相邻,优点是能靠下标随机存取,缺点是删除增加一个元素都是移动后面所有元素。
结构体指针可用->符号访问结构体的内部元素,p->data等价于(*p).data
NULL定义在头文件stddef.h中,也能自己定义宏,C语言没有空的概念,都是拿一个值替换
主函数
运行结果:
![](http://img.blog.csdn.net/20160416214929273?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
删除操作需要free()释放结点内存空间。
链式表跟顺序表的优缺点相反,删除插入方便,但不能随机存取。
线性表包括顺序存储和链式存储两种形式。
1、顺序表
首先定义宏,为线性表分配初始内存空间和再分配用定义结构体,内部定义指针作为线性表的基址,动态分配后就可以用下标访问,跟数组一样,数组a[10],a是指向第一个元素的指针,
#define LIST_INIT_SIZE 100 //首次分配的空间大小 #define LISTINCREMENT 10 //每次再分配增加的存储空间 typedef struct{ char *elem; //elem是基址 int length; //当前表长度 int listsize; //当前已分配存储空间大小 }SqList;
声明一个插入的函数,比较有代表性,其他操作就省略了。。
第一个参数传入SqList类型的引用,在函数操作中需修改变量值!
void ListInsert_Sq(SqList &L,int i,char e);
主函数首先声明SqList类型的变量,动态分配100个char型变量的内存空间,返回基址给elem,接着赋值length,listsize,初始化搞定。
main(){ SqList L; L.elem = (char *)malloc(LIST_INIT_SIZE * sizeof(char)); L.length = 0; L.listsize = LIST_INIT_SIZE; ListInsert_Sq(L,1,'a'); ListInsert_Sq(L,1,'b'); printf("L.elem[0]:%c, L.elem[1]:%c",L.elem[0],L.elem[1]); }插入操作函数实现:
void ListInsert_Sq(SqList &L,int i,char e){ if(i < 1 || i > L.length + 1) return; if(L.length >= L.listsize){ //分配空间已满 char *newbase; newbase = (char *)realloc(L.elem,(L.listsize + LISTINCREMENT) * sizeof(char)); //再分配,返回新基址 if(!newbase) exit(0); //分配失败 L.elem = newbase; L.listsize += LISTINCREMENT; } char *p,*q; p = &(L.elem[i - 1]); for(q = &(L.elem[L.length - 1]); p <= q; q--){ *(q + 1) = *(q); //后面所有元素向后移 } *p = e; L.length ++; }运行结果:
顺序表各元素在物理上也相邻,优点是能靠下标随机存取,缺点是删除增加一个元素都是移动后面所有元素。
2、链式表
同样首先定义结构体,链式表的每个结点 ,结结结结结点,包含一个基本数据,跟一个指向下一个结点的指针:#include <stdio.h> #include <stdlib.h> #include <stddef.h> typedef struct LNode{ char data; struct LNode *next; }LNode,*LinkList; //LNode是类型,LinkList是指针类型,可用以声明LNode类型的指针变量声明插入操作函数,有代表性
void ListInsert_L(LinkList &L,int i,char e); //传指针类型进来,又可能修改头结点值,传引用
结构体指针可用->符号访问结构体的内部元素,p->data等价于(*p).data
NULL定义在头文件stddef.h中,也能自己定义宏,C语言没有空的概念,都是拿一个值替换
主函数
main(){ LNode *head; head = (LinkList)malloc(sizeof(LNode)); head->next = NULL; //必须初始化,否则next指针指向随机内存单元,“野指针” ListInsert_L(head,1,'a'); ListInsert_L(head,1,'b'); for(LinkList p = head->next; p != NULL; p = p->next){ printf("%c\n",p->data); } }
void ListInsert_L(LinkList &L,int i,char e){ LNode *p; LNode *q; int j = 0; p = L; while(p && j < i - 1){ p = p->next; j ++; }//找到第i-1个结点 if(!p) return; //i值不合法 q = (LinkList)malloc(sizeof(LNode)); q->next = p->next; p->next = q; q->data = e; }
运行结果:
删除操作需要free()释放结点内存空间。
链式表跟顺序表的优缺点相反,删除插入方便,但不能随机存取。
相关文章推荐
- 数据结构学习笔记(八)--最短路径
- 数据结构_字符串的操作_c/c++
- 数据结构
- 数据结构——用数组实现的栈的基础功能
- 数据结构,栈和队列,停车场模型 ZC
- 纸牌发牌程序,数据结构
- 数据结构排序算法之简单插入排序
- 数据结构 二叉树
- 数据结构(线段树):BZOJ 3126: [Usaco2013 Open]Photo
- 面试题:java内存中的堆区和数据结构中的堆有什么区别
- 定义含有min函数的栈
- 数据结构 线性表中删除某一元素的程序
- 数据结构——单链表的基本操作
- (转载)动态规划:从新手到专家(关于动态规划算法最精彩的中文描述,没有之一)
- 数据结构中的赫夫曼树编码,KMP算法,图的深度优先遍历和广度优先遍历
- 数据结构(二叉树子系统:c语言实现)
- 数据结构(栈子系统:c实现)
- 数据结构(循环队列子系统:c实现)
- 二叉树的遍历详解(前序中序后序层次-递归和非递归)
- 多进程并发编程----进程间传递文件描述符基础~发送接收附属数据结构体介绍