LinearList
来源:互联网 发布:free mobile java 编辑:程序博客网 时间:2024/06/11 04:16
1、线性表的定义
4、顺序表的操作
5、单链表的操作
6、双链表的操作
线性表是具有相同特性数据元素的一个有限序列。该序列中所含元素的个数叫做线性表的长度,用n(n>0)表示。n可以为0,表示该线性表是一个空表。
2、线性表的逻辑特性只有一个表头元素,只有一个表尾元素,表头元素没有前驱,表尾元素没有后继,除表头和表位元素之外,其他元素只有一个直接前驱,也只有一个直接后继。
3、结构体定义
#define maxSize 100 //这里定义一个整型常量maxSize,值为100//1、顺序表的结构体定义typedef struct{ int data[maxSize]; //存放顺序元素的数组(默认是int型,可根据题目要求将int转换成其他的数据类型) int length; //存放顺序表的长度}Sqlist; //顺序表类型的定义//2、单链表结点定义typedef struct LNode{ int data; //data中存放结点数据域(默认是int型) struct LNode *next; //指向后继结点的指针}LNode; //定义单链表结点类型//3、双链表结点定义typedef struct DLNode{ int data; //data中存放结点数据域(默认是int型) struct DLNode *prior; //指向前驱结点的指针 struct DLNode *next; //指向后继结点的指针}DLNode; //定义双链表结点类型
4、顺序表的操作
//返回第一个比x大的元素的位置int findElem(Sqlist L, int x){ int i; for (i=0; i<L.length; ++i) { if (x < L.data[i]) //对顺序表中的元素从小到大逐个进行判断,看x是否小于当前所扫描到的元素,如果小于则返回当前位置i { return i; } } return i; //如果顺序表中不存在比x大的元素,则应将x插入表尾元素,返回i来标记这种情况(i<L.length这一句不成立,而退出for循环后,i正好指示了表尾元素之后的位置,同样也是正确的插入位置)}//移动元素、并插入新的元素void insertElem(Sqlist &L, int x) //L本身要发生变化,因此要使用引用型{ int p,i; p = findElem(L,x); //调用函数findElem()来找到插入位置p for (i=L.length-1; i>=p; --i) { L.data[i+1] = L.data[i]; //从右向左,逐个将元素右移一个位置 } L.data[p] = x; //将x放在插入位置p上 ++(L.length); //表内元素多了1个,因此表长自增1}//在顺序表中查找第一个值为e的元素算法int findElem(Sqlist L, int e){ int i; for (i=0; i<L.length; ++i) { if (e == L.data[i]) { return i; //若找到,则返回下标 } } return -1; //没找到,返回-1,作为失败标记}//在第P个位置插入元素eint insertElem(Sqlist &L, int p, int e) //L本身要发生改变,所以要有引用型{ int i; if (p<0 || p>L.length || L.length==maxSize) //位置错误或者表长已经达到顺序表的最大允许值,此时插入不成功,返回0 { return 0; } for (i=L.length-1; i>=p; --i) { L.data[i+1] = L.data[i]; //从后往前,逐个将元素往后移动一个位置 } L.data[p] = e; //将e放在插入位置P上 ++(L.length); //表内元素多了1个,长度自增1 return 1; //插入成功,返回1}//删除顺序表L中下标为p(0<=p<=length-1)的元素,成功返回1,否则返回0,并将被删除元素的值赋给e。int deleteElem(Sqlist &L, int p, int &e){ int i; if (p<0 || p>L.length-1) { return 0; //位置不对返回0,代表删除不成功 } e = L.data[p]; //将被删除元素的值赋给e for (i=p; i<L.length-1; ++i) //从p位置开始,将其后边的元素逐个前移一个位置 { L.data[i] = L.data[i+1]; } --(L.length); //表长减1 return 1; //删除成功,返回1}//初始化顺序表的算法//只需将length设置为0,如下:void initList(Sqlist &L) //L本身要发生改变,所以用引用型{ L.length = 0;}//求指定位置元素的算法//用e返回L中p(0<=p<=length-1)位置上的元素,如下:int getElem(Sqlist L, int p, int &e) //要改变,所以用引用型{ if (p<0 || p>L.length-1) //p值越界错误,返回0 { return 0; } e = L.data[p]; return 1;}
5、单链表的操作
//将两个递增的单链表归并成一个递增的单链表void merge(LNode *A, LNode *B, LNode *&C){ LNode *p = A->next; //p来跟踪A的最小值结点 LNode *q = B->next; //q来跟踪B的最小值结点 LNode *r; //r始终指向C的终端节点 C = A; //用A的头结点来做C的头结点 C->next = NULL; free(B); //B的头结点已经没用,因而释放掉 r = C; //r指向C,因为此时头结点也是终端节点 while (p != NULL && q != NULL) //当p和q都不为空时,选取p与q所指结点中较小者插入C的尾部 { /** 以下的if else语句中,r始终指向当前链表的终端结点,作为接纳新结点的一个媒介,通过它,新结点被链接入C并且重新指向新的终端结点,以便于接收下一个新结点,这里体现了建立链表的尾插法的思想 */ if (p->data <= q->data) { r-next = p; p = p->next; r = r->next; } else { r->next = q; q = q->next; r = r->next; } } r->next = NULL; //此句可去掉 if (p != NULL) //将p及p之后链接到C的尾部 { r->next = p; } if (q != NULL) //将q及q之后链接到C的尾部 { r->next = q; }}//尾插法建立单链表void createlistR(LNode *&C, int a[], int n) //要改变的变量用引用型{ LNode *s,*r; //s用来指向新申请的结点,r始终指向C的终端结点 int i; C = (LNode*)malloc(sizeof(LNode)); //申请C的头结点空间 C->next = NULL; r = C; //r指向头结点,因为此时头结点就是终端结点 for (i=0; i<n; ++i) //循环申请n个结点来接收数组a中的元素 { s = (LNode*)malloc(sizeof(LNode)); //s指向新申请的结点 s->data = a[i]; //用新申请的结点来接收a中的一个元素 r->next = s; //用r来接收新结点 r = r->next; //r指向终端结点,以便于接纳下一个到来的结点 } r->next = NULL; //数组a中所有的元素都已经装入链表C中,C的终端结点的指针域置为NULL,C建立完成}//头插法建立单链表void createlistF(LNode *&C, int a[], int n){ LNode *s; int i; C = (LNode*)malloc(sizeof(LNode)); C->next = NULL; for (i=0; i<n; ++i) { s = (LNode*)malloc(sizeof(LNode)); s->data = a[i]; //头插法的关键 s->next = C->next; //s所指新结点的指针域next指向C中的开始结点 C->next = s; //头结点的指针域next指向s结点,使得s成为新的开始结点 }}//利用头插法将两个递增的单链表归并成一个递减的单链表void merge(LNode *A, LNode *B, LNode *&C){ LNode *p = A->next; LNode *q = B->next; LNode *s; C = A; C->next = NULL; free(B); while (p != NULL && q != NULL) { if (p->data <= q->data) { s = p; p = p->next; s->next = C->next; C->next = s; } else { s = q; q = q->next; s->next = C->next; C->next = s; } } /** 下边这两个循环是和求递增归并序列不同的地方,必须将剩余元素逐个插入C的头部才能得到最终的递减序列 */ while (p != NULL) { s = p; p = p->next; s->next = C->next; C->next = s; } while (q != NULL) { s = q; q = q->next; s->next = C->next; C->next = s; }}//查找链表C(带头结点)中是否存在一个值为x的结点,若存在,则删除该结点并返回1,否则返回0int findAndDelete(LNode *C, int x){ LNode *p, *q; p = C; //查找部分开始 while (p->next != NULL) { if (p->next->data == x) { break; } p = p->next; } //查找部分结束 if (p->next == NULL) { return 0; } else { //删除部分开始 q = p->next; p->next = p->next->next; free(q); //删除部分结束 return 1; }}
6、双链表的操作
//尾插法建立双链表void createDlistR(DLNode *&L, int a[], int n){ DLNode *s, *r; int i; L = (DLNode*)malloc(sizeof(DLNode)); L->prior = NULL; L->next = NULL; r = L; //r始终指向终端结点,开始头结点也是尾结点 for (i=0; i<n; ++i) { s = (DLNode*)malloc(sizeof(DLNode)); s->data = a[i]; /** 下边3句将s插入到L的尾部,并且r指向s,s->prior = r;这一句是和建立单链表不同的地方 */ r->next = s; s->prior = r; r = s; } r->next = NULL;}//在双链表中查找元素x,并返回结点指针DLNode* findNode(DLNode *C, int x){ DLNode *p = C->next; while (p != NULL) { if (p->data == x) { break; } p = p->next; } return p; //如果找到,则p中内容是结点地址(循环因break结束);如果没找到,则p中内容是NULL(循环因p等于NULL而结束)。}//插入结点的算法//假设在双链表中p所指的结点之后插入一个结点s,其操作语句如下:s->next = p->next;s->next = p;p->next = s;s->next->prior = s; //假如p指向最后一个结点,则本行可去掉//删除结点的算法//设要删除双链表中p结点的后继结点,其操作语句如下:q = p->next;p->next = q->next;q->next->prior = p;free(q);
阅读全文
0 0
- LinearList
- C++ LinearList 线性表
- 线形表 LinearList
- 数据结构----作业1--LinearList
- 抽象类linearList
- 数据结构与算法(一)LinearList ADT
- 线性表LinearList的创建与使用
- 错误1error C2259: “LinearList<T>”: 不能实例化抽象类e:\datastructure\cap_1\cap_1\linearlist.h
- [C++]数据结构:公式化描述的线性表LinearList的创建与使用
- 数据结构算法与应用-C++语言描述(LinearList无法引用的问题)
- 1997年,初识互联网,直到2004年家里第一次上网。龟速的网络。
- AI 破解谷歌人机鉴别系统,文本验证码或将离场
- 沃尔玛测试货架扫描机器人,向无人超市又迈进一步
- 利用CNN建模脑皮层与图像:新研究提出可实现「读心术」的表征系统
- 综述论文:当前深度神经网络模型压缩和加速方法速览
- LinearList
- bzoj 2342: [Shoi2011]双倍回文
- <差分约束>luogu 3275 糖果
- 蚯蚓 NOIP2016 提高组 Day2 T2
- UVa11468
- <Data Visualization>1 ggplot2 图形语法
- 洛谷 1312 [NOIP2011] Mayan游戏 dfs+模拟
- bzoj 2287 【POJ Challenge】消失之物 背包动规
- bzoj 3747 [POI2015]Kinoman 线段树