数据结构学习1——线性表定义以及代码

  • 希望能够帮助到大家,希望大家一键三连。跪谢

  • 一、线性表的定义

  • 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 > p->data; 
    		 //尾插法主要语法    
    		 r->next = p;  
    		 r = p;
    	}
    //将尾节点为空,为其他程序while(p)防止出错
    	r->next = NULL;
    	return L;
    } // CreateList_L
  • 3.源程序

  • //1.头文件
    #include 
    #include 
    //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 > 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)"<> 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,使之仍然保持有序;

    数据结构学习1——线性表定义以及代码_第1张图片

    2.在单链表L上查找值为x的元素,若找到,p指向值为X的结点,若没找到,p为空;

  • 数据结构学习1——线性表定义以及代码_第2张图片

    3.在递增有序单链表L上删除大于mink小于maxk的元素;

  • 数据结构学习1——线性表定义以及代码_第3张图片

    4.在有序单链表L上删除多余的相同元素

    数据结构学习1——线性表定义以及代码_第4张图片

    5.实现单链表的就地逆置,即在原表的存储空间将线性表(a1,a2...,an)逆置为(an,an-1,...,a1)

    数据结构学习1——线性表定义以及代码_第5张图片

    6.假设两个按元素值递增有序排列的线性表AB,均以单链表作为存储结构,请编程实现:将A表和B表归并成一个按元素值递减有序排列的线性表C,并要求利用原表(即A表和B表的)结点空间存放表C

    数据结构学习1——线性表定义以及代码_第6张图片

    7.已知有单链表表示的线性表中含有三类字符的数据元素(如字母字符、数字字符和其它字符),试编写程序:构造三个以循环链表表示的线性表,使每个表中只含同一类的字符,且利用原表中的结点空间作为这三个表的结点空间,头结点可另辟空间。

    数据结构学习1——线性表定义以及代码_第7张图片

    8.将一个用循环链表表示的稀疏多项式分解成两个多项式,使这两个多项式中各自仅含奇次项或偶次项,并要求利用原链表中的结点空间来构成这两个链表。

    数据结构学习1——线性表定义以及代码_第8张图片

你可能感兴趣的:(数据结构,算法,数据结构,线性回归,链表,c++)