-
希望能够帮助到大家,希望大家一键三连。跪谢
-
一、线性表的定义
- 1.线性表是最简单、最常用的一种数据结构,一个线性表是n个数据元素的有限序列。其他的信息书上更加详细,避免因为自身理解不清楚,多说从而误人子弟。可以参考王卓老师视频
-
二、线性表代码
-
1.代码需求:
- 在递增有序单链表L上增加一个元素x,使之仍然保持有序;
- 在单链表L上查找值为x的元素,若找到,p指向值为X的结点,若没找到,p为空;
- 在递增有序单链表L上删除大于mink小于maxk的元素;
- 在有序单链表L上删除多余的相同元素
- 实现单链表的就地逆置,即在原表的存储空间将线性表(a1,a2...,an)逆置为(an,an-1,...,a1)
- 假设两个按元素值递增有序排列的线性表A和B,均以单链表作为存储结构,请编程实现:将A表和B表归并成一个按元素值递减有序排列的线性表C,并要求利用原表(即A表和B表的)结点空间存放表C。
- 已知有单链表表示的线性表中含有三类字符的数据元素(如字母字符、数字字符和其它字符),试编写程序:构造三个以循环链表表示的线性表,使每个表中只含同一类的字符,且利用原表中的结点空间作为这三个表的结点空间,头结点可另辟空间。
- 将一个用循环链表表示的稀疏多项式分解成两个多项式,使这两个多项式中各自仅含奇次项或偶次项,并要求利用原链表中的结点空间来构成这两个链表。
- 9.要求以菜单形式设计。
-
2.主要算法
- 1.头插法
-
Status ListInsert_L(LinkList &L,ElemType &e) { LNode* p = L->next,*q; LNode* s = (LinkList)malloc(sizeof(LNode)); //赋值操作为后面操作s s->data = e; //代换 q = L; while (p != NULL && e > p->data) { //做遍历 q = q->next; p = p->next; } //头插法的主要函数 s->next = p; q->next = s; return OK; }
- 2.尾插法
-
LinkList CreateList_L(LinkList& L, ElemType n) //初始数字型化链表 { //分配空间 L = (LinkList)malloc(sizeof(LNode)); LNode* p=NULL,*r; L->next = NULL; //将L的头节点给r r = L; p = L->next; cout << "请输入链表数据元素值" << endl; for (int i = 0; i <n;++i) //遍历循环输入 { p = (LinkList)malloc(sizeof(LNode)); cin >> p->data; //尾插法主要语法 r->next = p; r = p; } //将尾节点为空,为其他程序while(p)防止出错 r->next = NULL; return L; } // CreateList_L
-
3.源程序
-
//1.头文件 #include <iostream> #include <string> //2.数据类型 #define ERROR 0 #define OK 1 #define OVERFLOW -2 using namespace std; typedef int Status; typedef int ElemType; typedef char Elemtype; //3.定义多项式链式 typedef struct { double coef; //系数 int exp; //指数 }PTerm; //4.定义数字型链表 typedef struct LNode { ElemType data; // 数据域 struct LNode* next; // 指针域 } LNode, * LinkList; //5.定义字符型链表 typedef struct Lnode { Elemtype data; // 数据域 struct Lnode* next; // 指针域 } Lnode, * Linklist; //6.定义一元多项式链表 typedef struct PNode { PTerm data; struct PNode* next; }PolyNode,*PLink; typedef PNode* PLink; //7.创建数字型链表 LinkList CreateList_L(LinkList& L, ElemType n) //初始数字型化链表 { //分配空间 L = (LinkList)malloc(sizeof(LNode)); LNode* p=NULL,*r; L->next = NULL; r = L; p = L->next; cout << "请输入链表数据元素值" << endl; for (int i = 0; i <n;++i) //遍历循环输入 { p = (LinkList)malloc(sizeof(LNode)); cin >> p->data; //尾插法 r->next = p; r = p; } r->next = NULL; return L; } // CreateList_L //8.创建字符类型 Linklist CreateList_l(Linklist& L, Elemtype n) { //分配空间 L = (Linklist)malloc(sizeof(Lnode)); Lnode* p = NULL, * r; L->next = NULL; r = L; p = L->next; cout << "请输入链表数据元素值" << endl; for (int i = 0; i < n; ++i) //遍历循环输入 { p = (Linklist)malloc(sizeof(Lnode)); cin >> p->data; //尾插法 r->next = p; r = p; } r->next = NULL; return L; } // CreateList_l //9.初始化一元多项式链表 void InitPoly(PLink& P) { P = (PLink)malloc(sizeof(PNode)); //分配空间做指向 P->next = P; } //10.创建一元多项式链表 void Creat_P(PLink& P, int n) { int i; PLink r, s; P = (PLink)malloc(sizeof(PNode)); P->next = P; r = P; r->next = P; int a, b; for (i = 0; i < n; i++) { cin >> a; cin >> b; s = (PLink)malloc(sizeof(PNode)); // s->data=Data[i]; s->data.coef = a; s->data.exp = b; //尾插法 r->next = s; r = s; } r->next = P; } //11.打印数字型单链表 Status printer(LinkList& L) //打印链表 { LNode* p = L->next; //做遍历 while (p) { cout << p->data << " "; p = p->next; } cout << endl; return OK; } //12.打印字符型单链表 Status printer_l(Linklist& l) //打印链表 { Lnode* p = l->next; while (p) { cout << p->data << " "; p = p->next; } cout << endl; return OK; } //13.按值查找 Status Locate(LinkList &L, ElemType e) //按值查找 { int j = 1; LNode* p = L->next; if (e < 1) { return ERROR; } while (p != NULL &&p->data!=e) { p = p->next; //计数 j++; } return j; } //14.单链表插入 Status ListInsert_L(LinkList &L,ElemType &e) { LNode* p = L->next,*q; LNode* s = (LinkList)malloc(sizeof(LNode)); s->data = e; //代换 q = L; while (p != NULL && e > p->data) { //做遍历 q = q->next; p = p->next; } //插入 s->next = p; q->next = s; return OK; } //15.递增有序单链表删除相同元素 Status Delete_Equal(LinkList& L) { LNode* p, * q, * s; p = L->next; while (p) { //将p的头节点指向q q = p; while (q->next) { if (p->data == q->next->data) { s = q->next; q->next = s->next; free(s); } else { q = q->next; } } p = p->next; } return OK; } //16.递增有序单链表删除两数之间元素 LinkList Delete_Between(LinkList &L,int &mink,int &maxk) { LinkList p = L, q = NULL; while (p->next != NULL) { if (p->next->data >= mink && p->next->data <= maxk) //因为有头结点,所以判断的是next的值 { q = p->next; p->next = q->next; delete q; } else //加else才能保证当节点符合条件时,先删除该节点而不移动指针,这样指针可以判断已删除节点的下一个节点是否符合条件, //否则,满足条件的节点删除的同时会指针后移一位,会掠过已删除节点的下一个节点 p = p->next; } return p->next; } //17.单链表就地逆置 LinkList ListReverse_L(LinkList& L) { LNode* p = L->next; LNode* q; L->next = NULL; while (p != NULL) { //做插入 q = p; p = p->next; q->next = L->next; L->next = q; } return p; } //18.合并递增有序链表 LinkList addLinkList(LinkList& A, LinkList& B) { LNode* p = A->next; LNode* q = B->next; LNode* C = (LinkList)malloc(sizeof(LNode)); LNode* c = C; while (p != NULL && q != NULL) { if (q->data < p->data) { c->next = q; q = q->next; } else { c->next = p; p = p->next; } c = c->next; } //将其中一个空的连接到c上 c->next = p == NULL ? q : p; return C; } //19.分离一个混合数据链表 Status seprateList(Linklist& L,Linklist& L1,Linklist& L2,Linklist& L3) { Lnode* p = L->next; free(L); L1 = (Linklist)malloc(sizeof(Lnode)); L2 = (Linklist)malloc(sizeof(Lnode)); L3 = (Linklist)malloc(sizeof(Lnode)); Lnode *p1 = L1; Lnode* p2 = L2; Lnode* p3 = L3; while (p!=NULL) { Lnode* s = p; p = p->next; if ((s->data>='a'&&s->data<='z')|| (s->data >= 'A' && s->data <= 'Z')) { //尾插法 s->next = p1->next; p1->next = s; p1 = s; } else if ((s->data >= '0' && s->data <= '9')) { //尾插法 s->next = p2->next; p2->next = s; p2 = s; } else { //尾插法 s->next = p3->next; p3->next = s; p3 = s; } p1->next = NULL; p2->next = NULL; p3->next = NULL; } return OK; } //20.分离一元多项链表的奇偶次项 Status Separation_P(PLink& P) { PLink q, p, rear; int i = 0; rear = P; q = P->next; p = P; while (rear->next != P) { rear = rear->next; if (rear->data.exp % 2 == 0) { i++; } } while (i != 0) { if (q->data.exp % 2 == 0) { p->next = q->next; q->next = P; rear->next = q; rear = q; q = p->next; i--; } else { p = p->next; q = p->next; } } return OK; } //21.打印一元多项链表 void printer_P(PLink P) { PLink p; p = P->next; cout << "奇数次多项式为:" << endl; int flog = 0; while ((p->data.exp) % 2 != 0) { if (flog == 0) { cout << p->data.coef << "x^" << p->data.exp; } else { cout << "+" << p->data.coef << "x^" << p->data.exp; } //做循环和计数 p = p->next; flog++; } cout << endl; printf("偶数次多项式为:\n"); while (p != P) { cout << p->data.coef << "x^" << p->data.exp; if (p->next != P) { printf("+"); } p = p->next; } cout << endl; } //22.程序菜单项 void Menu() { cout << "*****************************************************" << endl; cout << "*1.在单链表L上查找值为x的元素 *" << endl; cout << "*2.在递增有序单链表L上增加一个元素x,使之仍然保持有序*" << endl; cout << "*3.在递增有序单链表L上删除大于mink小于maxk的元素 *" << endl; cout << "*4.在有序单链表L上删除多余的相同元素 *" << endl; cout << "*5.实现单链表的就地逆置 *" << endl; cout << "*6.两个单调递增单链表A、B归并成单调递减的单链表C *" << endl; cout << "*7.分离单链表L中的字母、数字和其他字符为3个单链表 *" << endl; cout << "*8.分离一元多项式L的奇次项和偶次项 *" << endl; cout << "*0.退出 * " << endl; cout << "****************************************************" << endl; cout << "请输入所选菜单(0-8)"<<endl; } //23.主函数 int main() { //数字型单链表定义 LNode* L, * p; //字符型单链表定义 Lnode* l, * L1, * L2, * L3; //一元多项链表定义 PLink P; int n; ElemType x; int mink, maxk; while (1) { Menu(); int menu; cin >> menu; switch (menu) { case 1: { cout << "请输入线性链表的长度" << endl; cin >> n; CreateList_L(L, n); cout << "当前的单链表为:" << endl; printer(L); cout << "请输入要查找的x的值" << endl; cin >> x; int p = Locate(L, x); cout << "x是链表的第" << p << "个数" << endl;; } break; case 2: { cout << "请输入线性链表的长度" << endl; cin >> n; cout << "输入单链表数据时要保证递增有序"; CreateList_L(L, n); cout << "当前的单链表为:" << endl; printer(L); cout << "请输入要插入的元素x" << endl; cin >> x; ListInsert_L(L, x); cout << "插入后的链表为" << endl; printer(L); } break; case 3: { cout << "请输入线性链表的长度" << endl; cin >> n; cout << "输入单链表数据时保证递增有序" << endl; CreateList_L(L, n); cout << "请输入mink和maxk的值" << endl; cin >> mink >> maxk; Delete_Between(L, mink, maxk); cout << "删除大于mink小于maxk元素后的链表为" << endl; cout << mink<<" " << maxk<<" "; printer(L); } break; case 4: { cout << "请输入线性链表的长度" << endl; cin >> n; cout << "输入单链表数据时保证递增有序" << endl; CreateList_L(L, n); cout << "当前的单链表为:" << endl; printer(L); Delete_Equal(L); cout << "删除相同元素后的链表为" << endl; printer(L); } break; case 5: { cout << "请输入线性链表的长度" << endl; cin >> n; cout << "输入一串单链表为" << endl; CreateList_L(L, n); cout << "逆置后的单链表为" << endl; ListReverse_L(L); printer(L); } break; case 6: { LNode* A, * B, *C; cout << "请输入递增有序链表A的长度" << endl; cin >> n; CreateList_L(A,n); cout << "请输入递增有序链表B的长度" << endl; cin >> n; CreateList_L(B, n); cout << "A、B合并后递减链表为" << endl; C=addLinkList(A, B); ListReverse_L(C); printer(C); } break; case 7: { cout << "创建链表包含数字、字母、符号" << endl; cout << "请输入线性链表的长度" << endl; cin >> n; CreateList_l(l, n); cout << "分开后的链表为" << endl; seprateList(l, L1, L2, L3); cout << "数字链表为" << endl; printer_l(L1); cout << "字母链表为" << endl; printer_l(L2); cout << "符号链表为" << endl; printer_l(L3); } break; case 8: { int n; cout << "请输入多项式的总个数:" << endl; cin >> n; cout << "请输入多项式的系数和指数" << endl; Creat_P(P, n); Separation_P(P); printer_P(P); } break; case 0: exit(0); } } }
以上的程序纯手撸,来着各方借鉴,建议使用VS2019编译,DEV可能会报错。建议大家不要做CV工程师。
-
4.程序测试
-
1.在递增有序单链表L上增加一个元素x,使之仍然保持有序;
2.在单链表L上查找值为x的元素,若找到,p指向值为X的结点,若没找到,p为空;
-
3.在递增有序单链表L上删除大于mink小于maxk的元素;
-
4.在有序单链表L上删除多余的相同元素
5.实现单链表的就地逆置,即在原表的存储空间将线性表(a1,a2...,an)逆置为(an,an-1,...,a1)
6.假设两个按元素值递增有序排列的线性表A和B,均以单链表作为存储结构,请编程实现:将A表和B表归并成一个按元素值递减有序排列的线性表C,并要求利用原表(即A表和B表的)结点空间存放表C。
7.已知有单链表表示的线性表中含有三类字符的数据元素(如字母字符、数字字符和其它字符),试编写程序:构造三个以循环链表表示的线性表,使每个表中只含同一类的字符,且利用原表中的结点空间作为这三个表的结点空间,头结点可另辟空间。
8.将一个用循环链表表示的稀疏多项式分解成两个多项式,使这两个多项式中各自仅含奇次项或偶次项,并要求利用原链表中的结点空间来构成这两个链表。
数据结构学习1——线性表定义以及代码
于 2022-06-29 19:06:13 首次发布