C++数据结构之线性表

顺序构建线性表

任务描述

本关任务:按照数据输入的顺序构建一个线性表。即如果输入的3个结点数据分别为1、2、3,则构建的线性表包含3个结点,且从前往后的结点数据分别为1、2、3。

相关知识

线性表(linear list)是一种数据结构,是由 n 个具有相同特性的数据元素构成的序列。

线性表中元素的个数 n 即为线性表的长度,当 n = 0 时称为空表。线性表的相邻元素之间存在着序偶关系。

如用( a[0] ,…… ,a[i-1] ,a[i] ,a[i+1] ,…… ,a[n-1] )表示一个线性表,则称 a[i-1] 是 a[i] 的前驱,a[i+1] 是 a[i] 的后继

线性表的特性

  1. 线性表中必存在唯一的一个“第一元素”;
  2. 线性表中必存在唯一的一个“最后元素” ;
  3. 除最后一个元素之外,均有唯一的后继;
  4. 除第一个元素之外,均有唯一的前驱。

线性表的一般操作

  1. 将线性表变为空表;
  2. 返回线性表的长度,即表中元素个数;
  3. 获取线性表某位置的元素;
  4. 定位某个元素在线性表中的位置;
  5. 在线性表中插入一个元素;
  6. 删除某个元素;
  7. 判断线性表是否为空;
  8. 遍历输出线性表的所有元素;
  9. 线性表排序。

线性表的表示方法
线性表可以用链表来实现。链表是通过指针链接在一起的一组数据项(结点)。

链表的每个结点都是同类型的结构,该结构中一般包含两类信息:

  • 数据域,存储业务相关的数据(如财务系统的数据域为财务信息,车辆管理系统的业务信息为车辆信息);
  • 指针域,用于构建结点的链接关系。单链表的实现只需要一个指针。

由于数据域跟线性表的构建无关(靠指针域就够了),所以本关所有程序的实现中线性表的数据域都只有一个整数。

单链表的形式如下:

在这里插入图片描述

如上图所示,该单链表共包含了4个结点,4个结点的数据域分别是28、52、2、96。每个结点还包含一个指针,指向下一个结点。最后一个结点的指针域置为“NULL”,表示后面没有结点了。

第一个结点的地址存放在一个指针变量 head 中( head 指向链表第一个结点, head 本身不是一个结点)。访问该单链表只需要知道 head 的值就可以了,因为通过 head 可以访问到第一个结点,通过第一个结点的指针域可以访问第二个结点 …… 直到访问链表中所有的结点。

要实现上述链表,只需要定义如下结构:

// 定义结点结构
struct node
{
    int data;     // 数据域
    node * next;     // 指针域,指向下一个结点
};

如下程序可以构建上述图中链表(其中:每个结点都是 node 类型的一个结构变量,head 则是node*类型的指针):

node a, b, c, d, *head;
head = &a;     // 让 head 指针指向结点 a
a.data = 28;     // 给 a 的数据域赋值
a.next = &b;     // 让 a 的指针域指向结点 b
b.data = 52;  b.next = &c;     // 给 b 的数据域赋值,并让 b 的指针域指向结点 c
c.data = 2;  c.next = &d;     // 给 c 的数据域赋值,并让 c 的指针域指向结点 d
d.data = 96;  d.next = NULL;     // 给 d 的数据域赋值,并将 d 的指针域置为 NULL,表示后面没有结点了

很显然,这样写程序比较麻烦,而且在不知道有多少结点的情况下也根本无法处理。怎么可以解决这个问题呢?

C 和 C++ 的内存动态分配方法可以很好的解决这个问题。C++ 提供了两种动态分配内存的方法:

  1. C 语言提供的 malloc 和 free 函数,代码如下:
node *t = (node *)malloc(sizeof(node));
t->data = 2;
free(t);
  • sizeof 是一个运算符,sizeof(node)用于计算并返回一个 node 类型变量所占内存空间的大小(字节数);
  • malloc(int n)用于申请动态分配 n 个字节大小的数据空间,并返回该空间的首地址;
  • (node )是类型转换运算符,malloc 函数返回的地址是void类型,转换成node类型后赋值给指针变量 t( t
    的类型是node
    )。

所以上面第一条语句执行后,指针 t 指向一块动态分配的内存空间,该空间大小为一个 node 类型变量的大小。

第二条语句通过指针 t 访问该空间(当作 node 变量)的数据域 data,给它赋值为2。free 函数用于释放 t 指向的动态分配空间(不需要该空间后再释放)。

  1. C++ 扩展的 new 和 delete 运算符,代码如下:
node *t = new node;
t->data = 2;
delete t;

那么使用动态内存分配的方法实现上述的单链表的代码如下:

node *head, *t, *p;
t = new node;     // 动态分配一个 node 结点的空间,并让 t 指向它
head = t;     // 该结点是第一个结点,让 head 指向它
t->data = 28;     // 给第一个结点的数据域赋值
p = new node;     // 动态分配第二个 node 结点的空间,并让 p 指向它
t->next = p;     // 修改第一个结点的指针域为第二个结点的地址(第一个结点的指针域指向第二个结点)
p->data = 52;     // 给第二个结点的数据域赋值
t=p;     // 让 t 指向最后一个结点
p = new node;     // 动态分配第三个 node 结点的空间,并让 p 指向它( p 不再指向第二个结点了)
t->next = p;     // 修改第二个结点的指针域为第三个结点的地址(第二个结点的指针域指向第三个结点)
p->data = 2;     // 给第三个结点的数据域赋值
t = p;     // 让 t 指向最后一个结点
p = new node;     // 动态分配第四个 node 结点的空间,并让 p 指向它( p 不再指向第三个结点了)
t->next = p;     // 修改第三个结点的指针域为第四个结点的地址(第三个结点的指针域指向第四个结点)
p->data = 96;     // 给第四个结点的数据域赋值
p->next = NULL;     // 给第四个结点的指针域置为 NULL,表示后面没有结点了

上述程序语句虽然好像变多了,程序也好像变复杂了,但细读会发现这段程序可以很方便地改成循环,这样处理后其实是使得程序更简单了,并且适用于任意多个结点的情况。

改成循环后,单链表里面可能包含0个或多个结点,如果包含多个结点,则下面程序中的语句可以让指针 t 指向链表的最后一个结点,具体代码如下:

node *t = head;     // t 指向第一个结点
// 如果 t->next 不为 NULL,即后面还有结点
while(t->next != NULL)
{
    t = t->next;     // 把 t 指向结点的指针域(下一个结点地址)赋值给 t,t 指向下一个结点
}
// 循环结束时,t->next 为 NULL,即 t 指向的结点后面没有结点了。

linearList.h

#include <iostream>
using namespace std;

// 定义结点结构
struct node
{
    int data;  // 数据域
    node * next;  //指针域,指向下一个结点
};

// 函数insertTail:链表尾部插入
// 参数:h-链表头指针,t-指向要插入的结点
// 返回值:插入结点后链表的首结点地址
node *insertTail(node *h, node *t);

// 函数printList:输出链表,每个数据之间用一个空格隔开
// 参数:h-链表头指针
void printList(node *h);

// 函数delList:删除链表,释放空间
// 参数:h-链表头指针
void delList(node *h);

linearList_1.cpp

#include "linearList.h"

node *insertTail(node *h, node *t)
{
    // 请在此添加代码,补全函数insertTail
    /********** Begin *********/
    if(h == NULL)
        return t;
    node *tmp = h;
    while(tmp->next)
        tmp = tmp->next;//跳转到最后一个
    tmp->next = t;
    return h;

    /********** End **********/
}

main.cpp

#include "linearList.h"

int main()
{
	int n,i;
	node *t;
	node *head=NULL; // Í·Ö¸ÕëΪNULL£¬±íʾÏßÐÔ±íΪ¿Õ£¬½áµãÊýΪ0
	// ÊäÈë½áµãÊý
	cin>>n;
	for(i=0;i<n;i++)
	{
		// Ϊнڵ㶯̬·ÖÅä¿Õ¼ä
		t = new node;
		cin>>t->data;  // ÊäÈë½áµãÊý¾Ý
		t->next=NULL;  // ½áµãÖ¸ÕëÓòֵΪ¿Õ
		// µ÷Óú¯Êý²åÈë½áµã
		head = insertTail(head, t);
	}
	// Êä³öÁ´±í
	printList(head);
	// ɾ³ý½áµã£¬ÊÍ·Å¿Õ¼ä
	delList(head);

	return 0;
}
// º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h;  // Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p)  // Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next;  // Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p;  // ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h;  // pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
// º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{// hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  // Êä³ö½áµãÊý¾Ý
		h=h->next;  // ½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; // Êä³ö»»Ðзû
}


逆序构建线性表

任务描述

本关任务:补全 insertHead 函数,实现将一个结点插入到一个链表头部的功能。

相关知识

在介绍如何将一个结点插入到一个链表头部之前,我们先假设该链表头指针为 head,则 head 中存放着链表当前头结点的地址。

如果要将指针变量 t 指向的新结点插入到链表头部,其实只需要将原来的头结点的地址存入 t 指向结点的指针域(也就是让 t 指向结点的指针域指向原来的头结点),然后 t 指向的新结点就成了新的头结点了。那么,如何将原来的头结点的地址存入 t 指向结点的指针域?

t 指向结点的指针域可以用t->next访问,原来头结点的地址在 head 中,所以下面的语句可以实现这个功能:

t->next = head;
又由于新结点( t 指向的结点)是新的头结点,其地址必须存入头指针 head 中,而 t 指向结点的地址存放在指针变量 t 中,所以下面的语句可以实现这个功能:

head = t;

编程要求

在右侧编辑器中的Begin-End之间补充代码,使函数实现将一个结点插入到一个链表头部(逆序构建线性表)的功能,且函数的返回值为插入结点的地址。

提示:在上一关实现的 insertTail 函数中将结点插入到链表尾部,实现了顺序构建线性表的功能,要逆序构建线性表只需要每次把新结点插到链表头部就可以了。

linearList.h

#include <iostream>
using namespace std;

// ¶¨Òå½áµã½á¹¹
struct node
{
    int data;  // Êý¾ÝÓò
    node * next;  // Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

// º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);

// º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);

// º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);

// º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

linearList_2.cpp

#include "linearList.h"

node * insertHead(node *h, node *t)
{
    // 请在此添加代码,补全函数insertHead
    /********** Begin *********/
    
    t->next = h;
    h =t;

    /********** End **********/
}

main.cpp

#include "linearList.h"

int main()
{
	int n,i;
	node *t;
	node *head=NULL; //头指针为NULL,表示线性表为空,结点数为0
	//输入结点数
	cin>>n;
	for(i=0;i<n;i++)
	{
		//为新节点动态分配空间
		t = new node;
		cin>>t->data; //输入结点数据
		t->next=NULL;  //结点指针域值为空
		//调用函数插入结点到链表头部
		head = insertHead(head, t);
	}
	//输出链表
	printList(head);
	//删除结点,释放空间
	delList(head);

	return 0;
}
//函数delList:删除链表,释放空间
//参数:h-链表头指针
void delList(node *h)
{
	node *p=h; //指针p指向头结点,第一个要删除的结点
	while(p) //这个结点是存在的
	{
		h = h->next; //头指针h指向下一个结点(下一个结点的地址存在当前结点的指针域中,即h->next中
		delete p; //删除p指向的结点
		p = h; //p指向当前的头结点,即下一个要删除的结点
	}
}
//函数printList:输出链表,每个数据之间用一个空格隔开
//参数:h-链表头指针
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//h为真,即h指向的结点存在,则输出该结点的数据
		cout<<" "<<h->data;  //输出结点数据
		h=h->next;  //将该结点的指针域赋值给h,h就指向了下一个结点
	}
	cout<<endl; //输出换行符
}

//函数insertTail:链表尾部插入
//参数:h-链表头指针,t-指向要插入的结点
//返回值:插入结点后链表的首结点地址
node *insertTail(node *h, node *t)
{
	if(h==NULL) //空链表单独处理
	{
		t->next=NULL; //链表尾指针置为NULL
		return t; //返回第一个结点的地址(即链表头指针)
	}
	//非空链表的情况
	node *p=h;
	//让p指向最后一个结点
	while(p->next)
		p=p->next;
	p->next = t; //让最后一个结点的指针域指向结点t
	t->next=NULL; //链表尾指针置为NULL
	return h;  //返回第一个结点的地址(即链表头指针)
}


排序构建线性表

任务描述

本关任务:补全 insertSort 函数,实现将一个结点按结点数据 data 从小到大的顺序插入到一个有序链表中。根据插入结点 data 的大小,插入点可能是链表头、尾或者中间某个位置。

相关知识

实现本关任务的关键分为两个步骤:

  • 一是找到插入点;
  • 二是插入结点。

如何找到插入点
插入点的定位可以使用两个指针( p 和 q ),定位步骤如下图所示:

在这里插入图片描述

上图中链表有4个结点,则共有5个可能的插入点。

用两个指针首先定位第一个插入点( step1 ,p 为 NULL ,q 指向第一个结点),如果插入结点的 data 小于 q 指向结点的 data ,则就是该插入点(两个指针指向的结点之间),否则两个指针一起往后移动( step2 );定位第二个插入点,判断条件依然是插入结点的 data 是否小于 q 指向的结点的 data,是则就是该插入点,否则两个指针往后平移( step3 );定位第三个插入点,…… ,直到最后当 q 指针为“NULL”时,说明插入结点的 data 比链表中所有数据都大,则插入点应该是链尾(第五个插入点)。插入点的定位操作可以很容易地用循环实现。

定位好插入点后,当 p 为“NULL”时,插入点是链表头部;当 q 为“NULL”时,插入点是链表尾部;否则,插入点为 p 和 q 指向的两个结点之间。

如何插入结点
上述定位好插入点后,接下来是插入结点。对于头部插入和尾部插入的内容前两关已做过介绍,本关只介绍中间插入的情况,即将 t 指向的结点插入到 p 和 q 指向的两个结点之间。

这种情况只需要让 p 指向结点的指针域指向 t 指向的结点, t 指向结点的指针域指向 q 指向的结点即可。具体参见下面代码:

p->next = t;
t->next = q;

编程要求

在右侧编辑器中的Begin-End之间补充代码,使函数实现将一个结点按结点数据 data 从小到大的顺序插入到一个有序链表中(排序构建线性表),且函数的返回值为插入结点后链表的首结点地址。

.h

#include <iostream>
using namespace std;

// ¶¨Òå½áµã½á¹¹
struct node
{
    int data;  // Êý¾ÝÓò
    node * next;  // Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

// º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t);

// º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);

// º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);

// º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);

// º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

.cpp

#include “linearList.h”

node * insertSort(node h, node t)
{
// ÇëÔÚ´ËÌí¼Ó´úÂ룬²¹È«º¯ÊýinsertSort
/
******** Begin *********/
node *pre = NULL;
node *cur = h;
while (cur && cur->datadata)
{
pre = cur;
cur = cur->next;
}
if (pre == NULL)
{
t->next = cur;
return t;
}
t->next = cur;
pre->next = t;
return h;

/********** End **********/

}

main.cpp

#include "linearList.h"

int main()
{
	int n,i;
	node *t;
	node *head=NULL; //Í·Ö¸ÕëΪNULL£¬±íʾÏßÐÔ±íΪ¿Õ£¬½áµãÊýΪ0
	//ÊäÈë½áµãÊý
	cin>>n;
	for(i=0;i<n;i++)
	{
		//Ϊнڵ㶯̬·ÖÅä¿Õ¼ä
		t = new node;
		cin>>t->data; //ÊäÈë½áµãÊý¾Ý
		t->next=NULL;  //½áµãÖ¸ÕëÓòֵΪ¿Õ
		//µ÷Óú¯Êý²åÈë½áµã£¬°´data´ÓСµ½´óÅÅÐò²åÈë
		head = insertSort(head, t);
	}
	//Êä³öÁ´±í
	printList(head);
	//ɾ³ý½áµã£¬ÊÍ·Å¿Õ¼ä
	delList(head);

	return 0;
}
//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h; //Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p) //Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next; //Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p; //ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h; //pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  //Êä³ö½áµãÊý¾Ý
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; //Êä³ö»»Ðзû
}

//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t)
{
	if(h==NULL) //¿ÕÁ´±íµ¥¶À´¦Àí
	{
		t->next=NULL; //Á´±íβָÕëÖÃΪNULL
		return t; //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
	}
	//·Ç¿ÕÁ´±íµÄÇé¿ö
	node *p=h;
	//ÈÃpÖ¸Ïò×îºóÒ»¸ö½áµã
	while(p->next)
		p=p->next;
	p->next = t; //ÈÃ×îºóÒ»¸ö½áµãµÄÖ¸ÕëÓòÖ¸Ïò½áµãt
	t->next=NULL; //Á´±íβָÕëÖÃΪNULL
	return h;  //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
}

//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t)
{
	t->next=h;
	return t;
}

查找元素

任务描述

本关任务:补全 search 函数,实现在一个链表中搜索包含指定数据的结点。如果链表中有多个结点包含该数据,则返回第一个。

相关知识

遍历列表元素
在线性表中查找特定元素是线性表的常用操作之一。由于链表结点都是动态内存分配得到的,在内存中不是连续存储,没法使用二分法之类的算法来实现信息检索,但可以使用顺序查找的方法。

顺序查找需要遍历整个链表,逐个检查每个结点是否满足条件。下面 printList 函数则可以遍历链表元素:

// 函数printList:输出链表,每个数据之间用一个空格隔开
// 参数:h-链表头指针

void printList(node *h)
{
    cout << "List:";
    while(h)
    {    // h 为真,即 h 指向的结点存在,则输出该结点的数据
        cout << " " << h->data;     // 输出结点数据
        h=h->next;     // 将该结点的指针域赋值给 h,h 就指向了下一个结点
    }
    cout << endl; // 输出换行符
}

编程要求

在右侧编辑器中的Begin-End之间补充代码,实现按顺序查找线性表中特定元素(链表和特定元素数据由平台提供,均已在主函数中获取),若找到该元素,则返回该元素对应的指针,否则返回 NULL。

.h

#include <iostream>
using namespace std;

// ¶¨Òå½áµã½á¹¹
struct node
{
    int data;  // Êý¾ÝÓò
    node * next;  // Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

// º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
// ·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num);

// º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t);

// º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);

// º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);

// º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);

// º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

.cpp

#include "linearList.h"

node * search(node * h, int num)
{
    // 请在此添加代码,补全函数search
    /********** Begin *********/
    while(h)
    {
    if (h->data == num)
        return h;
    h = h->next;
    }
    return NULL;

    /********** End **********/
}

main.cpp

#include "linearList.h"

int main()
{
	int n,i,num;
	node *t;
	node *head=NULL; //Í·Ö¸ÕëΪNULL£¬±íʾÏßÐÔ±íΪ¿Õ£¬½áµãÊýΪ0
	//ÊäÈë½áµãÊý
	cin>>n;
	for(i=0;i<n;i++)
	{
		//Ϊнڵ㶯̬·ÖÅä¿Õ¼ä
		t = new node;
		cin>>t->data; //ÊäÈë½áµãÊý¾Ý
		t->next=NULL;  //½áµãÖ¸ÕëÓòֵΪ¿Õ
		//¹¹½¨ÓÐÐòÁ´±í
		head = insertSort(head, t);
	}
	//ÊäÈëÒª²éÕÒµÄÊý
	cin>>num;
	//ÔÚÁ´±íÖвéÕÒnum
	node *np = search(head,num);
	//Êä³ö´Ónp¿ªÊ¼µÄºó°ë½ØÁ´±í£¨Èç¹ûnpΪNULL£¬ÔòÊä³ö¿ÕÁ´±í£©
	printList(np);
	//ɾ³ý½áµã£¬ÊÍ·Å¿Õ¼ä
	delList(head);

	return 0;
}
//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h; //Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p) //Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next; //Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p; //ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h; //pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  //Êä³ö½áµãÊý¾Ý
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; //Êä³ö»»Ðзû
}

//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t)
{
	if(h==NULL) //¿ÕÁ´±íµ¥¶À´¦Àí
	{
		t->next=NULL; //Á´±íβָÕëÖÃΪNULL
		return t; //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
	}
	//·Ç¿ÕÁ´±íµÄÇé¿ö
	node *p=h;
	//ÈÃpÖ¸Ïò×îºóÒ»¸ö½áµã
	while(p->next)
		p=p->next;
	p->next = t; //ÈÃ×îºóÒ»¸ö½áµãµÄÖ¸ÕëÓòÖ¸Ïò½áµãt
	t->next=NULL; //Á´±íβָÕëÖÃΪNULL
	return h;  //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
}

//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t)
{
	t->next=h;
	return t;
}

//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t)
{
	node *p=NULL,*q=h; //¶¨Î»µÚÒ»¸ö²åÈëµã£ºÁ´Ê×
	while(q && q->data<t->data) //²éÕÒ²åÈëµã
	{//Á½¸öÖ¸Õë²¢ÐкóÒÆ
		p=q;
		q=q->next;
	}
	if(p==NULL) //²åÈëÁ´Ê×
	{
		t->next = h;
		return t;
	}
	if(q==NULL) //²åÈëÁ´Î²
	{
		p->next = t;
		t->next = NULL;
		return h;
	}
	//²åÈëp¡¢qÖ®¼ä
	t->next=q;
	p->next=t;
	return h;
}

删除指定位置的结点

任务描述

本关任务:补全 delAt 函数,实现根据指定位置删除链表中对应的结点。

相关知识

删除链表结点
线性表的结点是有序号的,包含 n 个结点的线性表从链头到链尾的结点序号分别为0、1、…… 、n−1。删除线性表指定位置的操作也是常用的功能。

结点的删除可以根据结点位置的不同分为三种情况:删除链首结点、删除链尾结点、删除中间结点。

回答以下几个问题,解决本关问题就不难了:

  • 删除链首结点后,原来序号为1的结点成为新的链首结点,链表头指针也应该存储该结点的地址,该结点的地址原来存放在哪?
  • 删除链尾结点后,原来序号为n−2的结点成为新的链尾结点,该结点的指针域也应该置为“NULL”,表示链表的结束。怎么访问序号为n−2的结点的指针域?
  • 删除中间结点只需要将其前面结点的指针域修改为其后面结点的地址即可。例如删除序号为i的结点,需要将序号为i−1的结点的指针域修改为序号为i+1的结点地址。怎么访问序号为i−1的结点的指针域?序号为i+1的结点地址存放在哪?

编程要求
在右侧编辑器中的Begin-End之间补充代码,使函数实现删除线性表指定位置(链表和指定位置数据由平台提供,均已在主函数中获取)结点,且函数的返回值为删除结点后链表的首结点地址。

.h

#include <iostream>
using namespace std;

// ¶¨Òå½áµã½á¹¹
struct node
{
    int data;  // Êý¾ÝÓò
    node * next;  // Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

// º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
// ·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i);

// º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
// ·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num);

// º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t);

// º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);

// º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);

// º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);

// º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

.cpp

#include "linearList.h"

node * delAt(node * h, int i)
{
    // 请在此添加代码,补全函数delAt
    /********** Begin *********/
    node *p = NULL, *q = h; 
    for(int k = 0; k < i; k++)
    {
        if(q->next == NULL) 
        {
            return h;
  	}
        p = q;
        q = q->next;
    }
    if(p) 
    {
        
        p->next = q->next;
        delete q;
        return h;
    }
    else 
    {
        h = q->next; 
        delete q;
        return h;
    }


    /********** End **********/
}

main.cpp

#include "linearList.h"

int main()
{
	int n,i;
	node *t;
	node *head=NULL; //Í·Ö¸ÕëΪNULL£¬±íʾÏßÐÔ±íΪ¿Õ£¬½áµãÊýΪ0
	//ÊäÈë½áµãÊý
	cin>>n;
	for(i=0;i<n;i++)
	{
		//Ϊнڵ㶯̬·ÖÅä¿Õ¼ä
		t = new node;
		cin>>t->data; //ÊäÈë½áµãÊý¾Ý
		t->next=NULL;  //½áµãÖ¸ÕëÓòֵΪ¿Õ
		//°´ÊäÈë˳Ðò¹¹½¨Á´±í
		head = insertTail(head, t);
	}
	//ÊäÈëҪɾ³ý½áµãµÄÐòºÅ
	cin>>i;
	//ÔÚÁ´±íÖÐɾ³ýÐòºÅΪiµÄ½áµã
	head = delAt(head, i);
	//Êä³öÁ´±í
	printList(head);
	//ɾ³ý½áµã£¬ÊÍ·Å¿Õ¼ä
	delList(head);

	return 0;
}
//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h; //Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p) //Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next; //Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p; //ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h; //pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  //Êä³ö½áµãÊý¾Ý
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; //Êä³ö»»Ðзû
}

//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t)
{
	if(h==NULL) //¿ÕÁ´±íµ¥¶À´¦Àí
	{
		t->next=NULL; //Á´±íβָÕëÖÃΪNULL
		return t; //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
	}
	//·Ç¿ÕÁ´±íµÄÇé¿ö
	node *p=h;
	//ÈÃpÖ¸Ïò×îºóÒ»¸ö½áµã
	while(p->next)
		p=p->next;
	p->next = t; //ÈÃ×îºóÒ»¸ö½áµãµÄÖ¸ÕëÓòÖ¸Ïò½áµãt
	t->next=NULL; //Á´±íβָÕëÖÃΪNULL
	return h;  //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
}

//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t)
{
	t->next=h;
	return t;
}

//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t)
{
	node *p=NULL,*q=h; //¶¨Î»µÚÒ»¸ö²åÈëµã£ºÁ´Ê×
	while(q && q->data<t->data) //²éÕÒ²åÈëµã
	{//Á½¸öÖ¸Õë²¢ÐкóÒÆ
		p=q;
		q=q->next;
	}
	if(p==NULL) //²åÈëÁ´Ê×
	{
		t->next = h;
		return t;
	}
	if(q==NULL) //²åÈëÁ´Î²
	{
		p->next = t;
		t->next = NULL;
		return h;
	}
	//²åÈëp¡¢qÖ®¼ä
	t->next=q;
	p->next=t;
	return h;
}

//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num)
{
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(h->data==num)
			return h;
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	return NULL; //ûÕÒµ½°üº¬numµÄ½áµã
}

删除包含特定数据的结点

任务描述

本关任务:补全 delHas 函数,实现删除链表中包含特定数据的结点,如果有多个这样的结点,只删除第一个。

删除链表的结点时,有时候不知道结点在哪,只知道结点数据的特征,如删除成绩低于60的学生结点、删除学号为20160903的学生等。
.h

#include <iostream>
using namespace std;

// ¶¨Òå½áµã½á¹¹
struct node
{
    int data;  // Êý¾ÝÓò
    node * next;  // Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

// º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
// ·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n);

// º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
// ·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i);

// º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
// ·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num);

// º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t);

// º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);

// º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);

// º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);

// º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

.cpp

#include "linearList.h"

node * delHas(node * h, int n)
{
    // 请在此添加代码,补全函数delHas
    /********** Begin *********/
    node *p = NULL, *q = h; 
    
    if(h->data ==n)
    {
        h = h->next;
        return h;
    }
    
    while(q)
    {
        
        
        if (q->data == n)
        {    
            p->next= q->next;
            return h;
        }
        p = q;
        q = q->next;
    }
    return h;

    /********** End **********/
}

main.cpp

#include "linearList.h"

int main()
{
	int n,i,num;
	node *t;
	node *head=NULL; //Í·Ö¸ÕëΪNULL£¬±íʾÏßÐÔ±íΪ¿Õ£¬½áµãÊýΪ0
	//ÊäÈë½áµãÊý
	cin>>n;
	for(i=0;i<n;i++)
	{
		//Ϊнڵ㶯̬·ÖÅä¿Õ¼ä
		t = new node;
		cin>>t->data; //ÊäÈë½áµãÊý¾Ý
		t->next=NULL;  //½áµãÖ¸ÕëÓòֵΪ¿Õ
		//°´ÊäÈë˳Ðò¹¹½¨Á´±í
		head = insertTail(head, t);
	}
	//ÊäÈëҪɾ³ý½áµã°üº¬µÄÊý¾Ý
	cin>>num;
	//ɾ³ý°üº¬numµÄ½áµã
	head = delHas(head, num);
	//Êä³öÁ´±í
	printList(head);
	//ɾ³ý½áµã£¬ÊÍ·Å¿Õ¼ä
	delList(head);

	return 0;
}
//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h; //Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p) //Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next; //Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p; //ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h; //pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  //Êä³ö½áµãÊý¾Ý
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; //Êä³ö»»Ðзû
}

//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t)
{
	if(h==NULL) //¿ÕÁ´±íµ¥¶À´¦Àí
	{
		t->next=NULL; //Á´±íβָÕëÖÃΪNULL
		return t; //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
	}
	//·Ç¿ÕÁ´±íµÄÇé¿ö
	node *p=h;
	//ÈÃpÖ¸Ïò×îºóÒ»¸ö½áµã
	while(p->next)
		p=p->next;
	p->next = t; //ÈÃ×îºóÒ»¸ö½áµãµÄÖ¸ÕëÓòÖ¸Ïò½áµãt
	t->next=NULL; //Á´±íβָÕëÖÃΪNULL
	return h;  //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
}

//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t)
{
	t->next=h;
	return t;
}

//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t)
{
	node *p=NULL,*q=h; //¶¨Î»µÚÒ»¸ö²åÈëµã£ºÁ´Ê×
	while(q && q->data<t->data) //²éÕÒ²åÈëµã
	{//Á½¸öÖ¸Õë²¢ÐкóÒÆ
		p=q;
		q=q->next;
	}
	if(p==NULL) //²åÈëÁ´Ê×
	{
		t->next = h;
		return t;
	}
	if(q==NULL) //²åÈëÁ´Î²
	{
		p->next = t;
		t->next = NULL;
		return h;
	}
	//²åÈëp¡¢qÖ®¼ä
	t->next=q;
	p->next=t;
	return h;
}

//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num)
{
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(h->data==num)
			return h;
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	return NULL; //ûÕÒµ½°üº¬numµÄ½áµã
}

//º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i)
{
	if(i<0) //ÐòºÅ·Ç·¨£¬²»É¾³ý
		return h;
	node *p=NULL, *q = h; // ¶¨Î»É¾³ý½áµã£¬ÊÔͼÈÃqÖ¸ÏòҪɾ³ý½áµã£¬pÖ¸ÏòÆäÇ°ÃæµÄ½áµã
	for(int k=0;k<i;k++)
	{
		if(q->next==NULL) //ºóÃæûÓнáµãÁË£¬ÐòºÅ·Ç·¨
			return h;
		p=q;
		q=q->next;
	}
	if(p) //pÖ¸ÏòµÄ½áµã´æÔÚ£¬²»ÊÇɾ³ýÊ×½áµã
	{
		//ɾ³ýqÖ¸ÏòµÄ½áµã£¬ÈÃpÖ¸Ïò½áµãµÄÖ¸ÕëÓòÖ¸ÏòqµÄºóÐø½áµã
		p->next = q->next;
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
	else //ɾ³ýÊ×½áµã
	{
		h = q->next; //ÏÂÒ»¸ö½áµã³ÉÁËÊ×½áµã
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
}

线性表长度

任务描述

本关任务:编写 listLength 函数来求线性表的长度。

.h

#include <iostream>
using namespace std;

// ¶¨Òå½áµã½á¹¹
struct node
{
    int data;  // Êý¾ÝÓò
    node * next;  // Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

// º¯ÊýlistLength£º¼ÆËã²¢·µ»ØÁ´±íµÄ³¤¶È
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
// ·µ»ØÖµ£ºÁ´±í³¤¶È
int listLength(node * h);

// º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
// ·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n);

// º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
// ·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i);

// º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
// ·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num);

// º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t);

// º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);

// º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);

// º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
// ·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);

// º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
// ²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

.cpp

#include "linearList.h"

int listLength(node * h)
{
    // ÇëÔÚ´ËÌí¼Ó´úÂ룬²¹È«º¯ÊýlistLength
    /********** Begin *********/
    int num = 0;
    while(h)
    {
        num++;
        h = h->next;
    }
    return num;

    /********** End **********/
}

main.cpp

#include "linearList.h"

int main()
{
	int n;
	node *t;
	node *head=NULL; //Í·Ö¸ÕëΪNULL£¬±íʾÏßÐÔ±íΪ¿Õ£¬½áµãÊýΪ0
	//ÊäÈë½áµãÊý¾Ý£¬ÕýÊýΪÓÐЧÊý¾Ý
	cin>>n;
	while(n>0)
	{
		//Ϊнڵ㶯̬·ÖÅä¿Õ¼ä
		t = new node;
		t->data = n; //½áµãÊý¾Ý¸³Öµ
		t->next=NULL;  //½áµãÖ¸ÕëÓòֵΪ¿Õ
		//°´ÊäÈë˳Ðò¹¹½¨Á´±í
		head = insertTail(head, t);
		cin>>n;
	}
	//¼ÆËãÁ´±í³¤¶È
	n = listLength(head);
	//Êä³öÁ´±í³¤¶È
	cout<<"List length:"<<n<<endl;
	//ɾ³ý½áµã£¬ÊÍ·Å¿Õ¼ä
	delList(head);

	return 0;
}
//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h; //Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p) //Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next; //Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p; //ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h; //pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  //Êä³ö½áµãÊý¾Ý
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; //Êä³ö»»Ðзû
}

//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t)
{
	if(h==NULL) //¿ÕÁ´±íµ¥¶À´¦Àí
	{
		t->next=NULL; //Á´±íβָÕëÖÃΪNULL
		return t; //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
	}
	//·Ç¿ÕÁ´±íµÄÇé¿ö
	node *p=h;
	//ÈÃpÖ¸Ïò×îºóÒ»¸ö½áµã
	while(p->next)
		p=p->next;
	p->next = t; //ÈÃ×îºóÒ»¸ö½áµãµÄÖ¸ÕëÓòÖ¸Ïò½áµãt
	t->next=NULL; //Á´±íβָÕëÖÃΪNULL
	return h;  //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
}

//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t)
{
	t->next=h;
	return t;
}

//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t)
{
	node *p=NULL,*q=h; //¶¨Î»µÚÒ»¸ö²åÈëµã£ºÁ´Ê×
	while(q && q->data<t->data) //²éÕÒ²åÈëµã
	{//Á½¸öÖ¸Õë²¢ÐкóÒÆ
		p=q;
		q=q->next;
	}
	if(p==NULL) //²åÈëÁ´Ê×
	{
		t->next = h;
		return t;
	}
	if(q==NULL) //²åÈëÁ´Î²
	{
		p->next = t;
		t->next = NULL;
		return h;
	}
	//²åÈëp¡¢qÖ®¼ä
	t->next=q;
	p->next=t;
	return h;
}

//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num)
{
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(h->data==num)
			return h;
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	return NULL; //ûÕÒµ½°üº¬numµÄ½áµã
}

//º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i)
{
	if(i<0) //ÐòºÅ·Ç·¨£¬²»É¾³ý
		return h;
	node *p=NULL, *q = h; // ¶¨Î»É¾³ý½áµã£¬ÊÔͼÈÃqÖ¸ÏòҪɾ³ý½áµã£¬pÖ¸ÏòÆäÇ°ÃæµÄ½áµã
	for(int k=0;k<i;k++)
	{
		if(q->next==NULL) //ºóÃæûÓнáµãÁË£¬ÐòºÅ·Ç·¨
			return h;
		p=q;
		q=q->next;
	}
	if(p) //pÖ¸ÏòµÄ½áµã´æÔÚ£¬²»ÊÇɾ³ýÊ×½áµã
	{
		//ɾ³ýqÖ¸ÏòµÄ½áµã£¬ÈÃpÖ¸Ïò½áµãµÄÖ¸ÕëÓòÖ¸ÏòqµÄºóÐø½áµã
		p->next = q->next;
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
	else //ɾ³ýÊ×½áµã
	{
		h = q->next; //ÏÂÒ»¸ö½áµã³ÉÁËÊ×½áµã
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
}

//º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n)
{
	node *p=NULL, *q=h; //pΪҪɾ³ý½áµãµÄÇ°½áµã£¬qÖ¸ÏòҪɾ³ý½áµã
	while(q)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(q->data==n)
			break; //ÕÒµ½ÁË
		if(q->next==NULL)//ºóÃæûÓнáµãÁË£¬Ã»ÓнáµãÂú×ãÌõ¼þ
			return h; //²»É¾³ý£¬Ö±½Ó·µ»Ø
		//¼ÌÐøÍùºóÕÒ£¬Á½¸öÖ¸ÕëÒ»ÆðºóÒÆ
		p=q;
		q=q->next;
	}
	//ɾ³ýqÖ¸ÏòµÄ½áµã
	if(p==NULL)//ɾ³ýÍ·½áµã
	{
		h=q->next;//ÏÂÒ»¸ö½áµã±ä³ÉÍ·½áµã
		delete q;//ɾ³ý½áµã
		return h;
	}
	//²»ÊÇÍ·½áµã
	p->next=q->next;//°ÑqÖ¸Ïò½áµãµÄÖ¸ÕëÓò£¨qºóÃæ½áµãµÄµØÖ·£©¸³Öµ¸øpÖ¸Ïò½áµãµÄÖ¸ÕëÓò
	return h;
}

线性表应用一:栈

任务描述

本关任务:用前面已经实现的线性表来实现一个整数栈(栈里的数据是整数)。共需要补全三个函数(也是栈的基本功能):判断栈空的 empty 函数、压栈的 push 函数和弹栈的 pop 函数。

相关知识


栈( stack )又名堆栈,是一种功能受限的线性表,具有先进后出的特性。

其限制为仅允许在线性表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。

  • 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;
  • 从一个栈删除元素又称作出栈、弹栈或退栈,它是把栈顶元素删除掉,使其下面的元素成为新的栈顶元素。

接下来首先声明结构类型:

// 定义结点结构

struct node
{
    int data;     // 数据域
    node * next;     // 指针域,指向下一个结点
};

typedef node * intStack; // 定义类型别名,intStack 即相当于 node*
定义 intStack 是为了使程序的可读性更好一些。因为本关是用线性表实现栈,而访问一个线性表其实只需要一个链表头指针就可以了,intStack 实际上就是node*类型,所以后面可以这样声明栈 sk :

intStack sk = NULL;     // 声明栈 sk,并初始化为空栈(空线性表)

实际上 sk 就是一个node*类型的指针,用它可以访问一个线性表,也就可以看成一个栈了。

编程要求

在右侧编辑器中的Begin-End之间补充代码,完成 empty 、pop 和 push 三个函数,以实现判断栈空、弹栈和压栈的功能。具体要求如下:

  • 函数 empty 判断栈 sk 是否为空,为空则返回 true,否则返回 false;
  • 函数 pop 实现从栈 sk 中弹出栈顶元素,参数 sk,传引用,因为弹栈可能会改变 sk 的值,返回值为弹栈弹出的数据,如果栈空,则返回
    -1 ;
  • 函数 push 实现压栈功能,将 n 压入栈 sk 中,参数 sk 为传引用,因为压栈可能会改变 sk的值,由于栈使用链表实现,只要还有内存,压栈都会成功。

LinearList.h

#include <iostream>
using namespace std;

//¶¨Òå½áµã½á¹¹
struct node
{
	int data;  //Êý¾ÝÓò
	node * next;  //Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

//º¯ÊýlistLength£º¼ÆËã²¢·µ»ØÁ´±íµÄ³¤¶È
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
//·µ»ØÖµ£ºÁ´±í³¤¶È
int listLength(node * h);
//º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n);
//º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i);
//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num);
//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t);
//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);
//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);
//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

LinearList.cpp

#include "linearList.h"

//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h; //Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p) //Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next; //Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p; //ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h; //pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  //Êä³ö½áµãÊý¾Ý
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; //Êä³ö»»Ðзû
}

//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t)
{
	if(h==NULL) //¿ÕÁ´±íµ¥¶À´¦Àí
	{
		t->next=NULL; //Á´±íβָÕëÖÃΪNULL
		return t; //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
	}
	//·Ç¿ÕÁ´±íµÄÇé¿ö
	node *p=h;
	//ÈÃpÖ¸Ïò×îºóÒ»¸ö½áµã
	while(p->next)
		p=p->next;
	p->next = t; //ÈÃ×îºóÒ»¸ö½áµãµÄÖ¸ÕëÓòÖ¸Ïò½áµãt
	t->next=NULL; //Á´±íβָÕëÖÃΪNULL
	return h;  //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
}

//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t)
{
	t->next=h;
	return t;
}

//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t)
{
	node *p=NULL,*q=h; //¶¨Î»µÚÒ»¸ö²åÈëµã£ºÁ´Ê×
	while(q && q->data<t->data) //²éÕÒ²åÈëµã
	{//Á½¸öÖ¸Õë²¢ÐкóÒÆ
		p=q;
		q=q->next;
	}
	if(p==NULL) //²åÈëÁ´Ê×
	{
		t->next = h;
		return t;
	}
	if(q==NULL) //²åÈëÁ´Î²
	{
		p->next = t;
		t->next = NULL;
		return h;
	}
	//²åÈëp¡¢qÖ®¼ä
	t->next=q;
	p->next=t;
	return h;
}

//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num)
{
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(h->data==num)
			return h;
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	return NULL; //ûÕÒµ½°üº¬numµÄ½áµã
}

//º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i)
{
	if(i<0) //ÐòºÅ·Ç·¨£¬²»É¾³ý
		return h;
	node *p=NULL, *q = h; // ¶¨Î»É¾³ý½áµã£¬ÊÔͼÈÃqÖ¸ÏòҪɾ³ý½áµã£¬pÖ¸ÏòÆäÇ°ÃæµÄ½áµã
	for(int k=0;k<i;k++)
	{
		if(q->next==NULL) //ºóÃæûÓнáµãÁË£¬ÐòºÅ·Ç·¨
			return h;
		p=q;
		q=q->next;
	}
	if(p) //pÖ¸ÏòµÄ½áµã´æÔÚ£¬²»ÊÇɾ³ýÊ×½áµã
	{
		//ɾ³ýqÖ¸ÏòµÄ½áµã£¬ÈÃpÖ¸Ïò½áµãµÄÖ¸ÕëÓòÖ¸ÏòqµÄºóÐø½áµã
		p->next = q->next;
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
	else //ɾ³ýÊ×½áµã
	{
		h = q->next; //ÏÂÒ»¸ö½áµã³ÉÁËÊ×½áµã
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
}

//º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n)
{
	node *p=NULL, *q=h; //pΪҪɾ³ý½áµãµÄÇ°½áµã£¬qÖ¸ÏòҪɾ³ý½áµã
	while(q)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(q->data==n)
			break; //ÕÒµ½ÁË
		if(q->next==NULL)//ºóÃæûÓнáµãÁË£¬Ã»ÓнáµãÂú×ãÌõ¼þ
			return h; //²»É¾³ý£¬Ö±½Ó·µ»Ø
		//¼ÌÐøÍùºóÕÒ£¬Á½¸öÖ¸ÕëÒ»ÆðºóÒÆ
		p=q;
		q=q->next;
	}
	//ɾ³ýqÖ¸ÏòµÄ½áµã
	if(p==NULL)//ɾ³ýÍ·½áµã
	{
		h=q->next;//ÏÂÒ»¸ö½áµã±ä³ÉÍ·½áµã
		delete q;//ɾ³ý½áµã
		return h;
	}
	//²»ÊÇÍ·½áµã
	p->next=q->next;//°ÑqÖ¸Ïò½áµãµÄÖ¸ÕëÓò£¨qºóÃæ½áµãµÄµØÖ·£©¸³Öµ¸øpÖ¸Ïò½áµãµÄÖ¸ÕëÓò
	return h;
}

//º¯ÊýlistLength£º¼ÆËã²¢·µ»ØÁ´±íµÄ³¤¶È
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
//·µ»ØÖµ£ºÁ´±í³¤¶È
int listLength(node * h)
{
	int n=0;
	while(h)
	{
		n++;
		h=h->next;
	}
	return n;
}


mstack.h

#include "linearList.h"

typedef node * intStack;  // ¶¨ÒåÀàÐͱðÃû£¬intStack¼´Ï൱ÓÚnode*

// º¯Êýempty£ºÅжÏÕ»skÊÇ·ñΪ¿Õ
// ²ÎÊý£ºsk-Õ»
// ·µ»ØÖµ£ºtrue-skΪ¿Õ£¬false-sk²»Îª¿Õ
bool empty(intStack sk);

// º¯Êýpop£º´ÓskÖе¯Õ»
// ²ÎÊý£ºsk-Õ»£¬´«ÒýÓ㬵¯Õ»¿ÉÄÜ»á¸Ä±äskµÄÖµ£¬n-ҪѹջµÄÕûÊý
// ·µ»ØÖµ£ºµ¯Õ»µÄµ¯³öµÄÕûÊý£¬Èç¹ûÕ»¿Õ£¬·µ»Ø-1
int pop(intStack &sk);

// º¯Êýpush£ºÑ¹Õ»£¬½«ÕûÊýnѹÈëÕ»skÖÐ
// ²ÎÊý£ºsk-Õ»£¬´«ÒýÓã¬Ñ¹Õ»»á¸Ä±äskµÄÖµ£¬n-ҪѹջµÄÕûÊý
// ·µ»ØÖµ£ºÎÞ£¬²ÉÓÃÁ´±íʵÏÖÕ»£¬Ö»Òª»¹ÓÐÄڴ棬ѹջ¶¼»á³É¹¦
void push(intStack &sk, int n);

mstack.cpp

#include "mstack.h"

// 函数empty:判断栈sk是否为空
// 参数:sk-栈
// 返回值:true-sk为空,false-sk不为空
bool empty(intStack sk)
{
    // 请在此添加代码,补全函数empty
    /********** Begin *********/
    return (listLength(sk) == 0);

    /********** End **********/
}

// 函数pop:弹栈
// 参数:sk-栈,传引用,弹栈可能会改变sk的值
// 返回值:弹栈的弹出的整数,如果栈空,返回-1
int pop(intStack &sk)
{
    // 请在此添加代码,补全函数pop
    /********** Begin *********/
    if(empty(sk))  // 栈空,返回-1
        return -1;
    int n = sk->data;  // 获取栈顶结点(链首结点)的数据
    sk = delAt(sk,0);  // 删除首结点(弹栈,第一个结点出栈)
    return n;  // 返回弹栈数据


    /********** End **********/
}

// 函数push:压栈,将整数n压入栈sk中
// 参数:sk-栈,传引用,压栈会改变sk的值,n-要压栈的整数
// 返回值:无,采用链表实现栈,只要还有内存,压栈都会成功
void push(intStack &sk, int n)
{
    // 请在此添加代码,补全函数push
    /********** Begin *********/
    node *p = new node;
    p->data = n;
    // 压栈(插入链首)
    sk = insertHead(sk,p);

    /********** End **********/
}

test.cpp

#include "mstack.h"

int main()
{
	intStack sk=NULL; //ÉùÃ÷Õ»sk£¬²¢³õʼ»¯Îª¿ÕÕ»£¨¿ÕÏßÐÔ±í£©
	int command; //ÊäÈëÖ¸Á1-ѹջ£¬0-µ¯Õ»£¬-1-Í˳ö£¬ÆäËü-·Ç·¨²Ù×÷
	int n;
	//ÊäÈëÖ¸Áî
	cin>>command;
	while(command!=-1)
	{
		switch(command) 
		{
		case 0:
			if(!empty(sk))
			{//Õ»·Ç¿Õ
				n = pop(sk); //µ¯Õ»£¬µ¯³öµÄÖµ¸øn
				cout<<n<<endl; //Êä³öµ¯Õ»µÄÖµ
			}
			else
				cout<<"Stack empty"<<endl;
			break;
		case 1:
			cin>>n; //ÊäÈëҪѹջµÄÊý¾Ý
			push(sk,n);
			cout<<"push "<<n<<endl;
			break;
		default:;
		}
		cin>>command;//ÊäÈëÏÂÒ»ÌõÖ¸Áî
	}
	//ɾ³ýÕ»
	delList(sk);

	return 0;
}

线性表应用二:队列

任务描述

本关任务:用前面已经实现的线性表来实现一个整数队列(队列里的数据是整数)。共需要补全三个函数(也是队列的基本功能):判断队列空的 queueEmpty 函数、入列的 enQueue 函数和出列的 deQueue 函数。

相关知识

队列
队列是一种功能受限的线性表,具有先进先出的特性。队列仅允许从一头出列(这一头称为队列头),从另外一头入列(队列尾)。

  • 入列操作是将结点插入到队列尾(该结点称为新的队列尾);
  • 出列操作是从队列头删除头结点,并获取删除节点的数据(原头结点的后继结点为新的头结点)。

接下来首先声明结构类型:

// 定义结点结构
struct node
{
    int data;     // 数据域
    node * next;     // 指针域,指向下一个结点
};

typedef node * intQueue; // 定义类型别名,intQueue 即相当于 node*
定义 intQueue 是为了使程序的可读性更好一些。因为本关是用线性表实现队列,而访问一个线性表其实只需要一个链表头指针就可以了,intQueue 实际上就是node*类型,所以后面可以这样声明队列 iq :

intQueue iq = NULL;  // 声明队列 iq,并初始化为空队列(空线性表)

实际上 iq 就是一个node*类型的指针,用它可以访问一个线性表,也就可以看成一个队列。

编程要求

在右侧编辑器中的Begin-End之间补充代码,完成 queueEmpty 、enQueue 和 deQueue 三个函数,以分别判断队列是否为空、入列和出列的要求。具体要求如下:

  • 函数 queueEmpty 判断队列 iq 是否为空,为空则返回 true,否则返回 false;
  • 函数 enQueue 实现将整数 num 入列到队列 iq。没有返回值,因为采用链表实现队列,只要还有内存,入列总会成功;
  • 函数 deQueue 实现从队列 iq 出列,如果队列非空,则返回出列的数据,否则返回−1。
    LinearList.h
#include <iostream>
using namespace std;

//¶¨Òå½áµã½á¹¹
struct node
{
	int data;  //Êý¾ÝÓò
	node * next;  //Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

//º¯ÊýlistLength£º¼ÆËã²¢·µ»ØÁ´±íµÄ³¤¶È
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
//·µ»ØÖµ£ºÁ´±í³¤¶È
int listLength(node * h);
//º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n);
//º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i);
//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num);
//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t);
//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);
//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);
//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

LinearList.cpp

#include "linearList.h"

//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h; //Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p) //Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next; //Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p; //ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h; //pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  //Êä³ö½áµãÊý¾Ý
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; //Êä³ö»»Ðзû
}

//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t)
{
	if(h==NULL) //¿ÕÁ´±íµ¥¶À´¦Àí
	{
		t->next=NULL; //Á´±íβָÕëÖÃΪNULL
		return t; //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
	}
	//·Ç¿ÕÁ´±íµÄÇé¿ö
	node *p=h;
	//ÈÃpÖ¸Ïò×îºóÒ»¸ö½áµã
	while(p->next)
		p=p->next;
	p->next = t; //ÈÃ×îºóÒ»¸ö½áµãµÄÖ¸ÕëÓòÖ¸Ïò½áµãt
	t->next=NULL; //Á´±íβָÕëÖÃΪNULL
	return h;  //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
}

//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t)
{
	t->next=h;
	return t;
}

//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t)
{
	node *p=NULL,*q=h; //¶¨Î»µÚÒ»¸ö²åÈëµã£ºÁ´Ê×
	while(q && q->data<t->data) //²éÕÒ²åÈëµã
	{//Á½¸öÖ¸Õë²¢ÐкóÒÆ
		p=q;
		q=q->next;
	}
	if(p==NULL) //²åÈëÁ´Ê×
	{
		t->next = h;
		return t;
	}
	if(q==NULL) //²åÈëÁ´Î²
	{
		p->next = t;
		t->next = NULL;
		return h;
	}
	//²åÈëp¡¢qÖ®¼ä
	t->next=q;
	p->next=t;
	return h;
}

//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num)
{
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(h->data==num)
			return h;
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	return NULL; //ûÕÒµ½°üº¬numµÄ½áµã
}

//º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i)
{
	if(i<0) //ÐòºÅ·Ç·¨£¬²»É¾³ý
		return h;
	node *p=NULL, *q = h; // ¶¨Î»É¾³ý½áµã£¬ÊÔͼÈÃqÖ¸ÏòҪɾ³ý½áµã£¬pÖ¸ÏòÆäÇ°ÃæµÄ½áµã
	for(int k=0;k<i;k++)
	{
		if(q->next==NULL) //ºóÃæûÓнáµãÁË£¬ÐòºÅ·Ç·¨
			return h;
		p=q;
		q=q->next;
	}
	if(p) //pÖ¸ÏòµÄ½áµã´æÔÚ£¬²»ÊÇɾ³ýÊ×½áµã
	{
		//ɾ³ýqÖ¸ÏòµÄ½áµã£¬ÈÃpÖ¸Ïò½áµãµÄÖ¸ÕëÓòÖ¸ÏòqµÄºóÐø½áµã
		p->next = q->next;
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
	else //ɾ³ýÊ×½áµã
	{
		h = q->next; //ÏÂÒ»¸ö½áµã³ÉÁËÊ×½áµã
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
}

//º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n)
{
	node *p=NULL, *q=h; //pΪҪɾ³ý½áµãµÄÇ°½áµã£¬qÖ¸ÏòҪɾ³ý½áµã
	while(q)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(q->data==n)
			break; //ÕÒµ½ÁË
		if(q->next==NULL)//ºóÃæûÓнáµãÁË£¬Ã»ÓнáµãÂú×ãÌõ¼þ
			return h; //²»É¾³ý£¬Ö±½Ó·µ»Ø
		//¼ÌÐøÍùºóÕÒ£¬Á½¸öÖ¸ÕëÒ»ÆðºóÒÆ
		p=q;
		q=q->next;
	}
	//ɾ³ýqÖ¸ÏòµÄ½áµã
	if(p==NULL)//ɾ³ýÍ·½áµã
	{
		h=q->next;//ÏÂÒ»¸ö½áµã±ä³ÉÍ·½áµã
		delete q;//ɾ³ý½áµã
		return h;
	}
	//²»ÊÇÍ·½áµã
	p->next=q->next;//°ÑqÖ¸Ïò½áµãµÄÖ¸ÕëÓò£¨qºóÃæ½áµãµÄµØÖ·£©¸³Öµ¸øpÖ¸Ïò½áµãµÄÖ¸ÕëÓò
	return h;
}

//º¯ÊýlistLength£º¼ÆËã²¢·µ»ØÁ´±íµÄ³¤¶È
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
//·µ»ØÖµ£ºÁ´±í³¤¶È
int listLength(node * h)
{
	int n=0;
	while(h)
	{
		n++;
		h=h->next;
	}
	return n;
}


mqueue.h

#include "linearList.h"

typedef node * intQueue;  // ¶¨ÒåÀàÐͱðÃû£¬intQueue¼´Ï൱ÓÚnode*

// º¯ÊýqueueEmpty£ºÅж϶ÓÁÐiqÊÇ·ñΪ¿Õ
// ²ÎÊý£ºiq-ÕûÊý¶ÓÁÐ
// ·µ»ØÖµ£ºtrue-¶ÓÁÐiqΪ¿Õ£¬false-iq²»Îª¿Õ
bool queueEmpty(intQueue iq);

// º¯ÊýenQueue£º½«ÕûÊýnumÈëÁе½iq
// ²ÎÊý£ºiq-ÕûÊý¶ÓÁУ¬´«ÒýÓã¬ÈëÁÐÓпÉÄܸıä¶ÓÁÐÍ·Ö¸Õ룬num-ÈëÁеÄÕûÊý
// ·µ»ØÖµ£ºÎÞ£¬Ö»Òª»¹ÓÐÄڴ棬ÈëÁÐ×Ü»á³É¹¦
void enQueue(intQueue &iq, int num);

// º¯ÊýdeQueue£º³öÁÐ
// ²ÎÊý£ºiq-ÕûÊý¶ÓÁУ¬´«ÒýÓ㬳öÁÐÓпÉÄܸıä¶ÓÁÐÍ·Ö¸Õë
// ·µ»ØÖµ£º³öÁнáµãµÄÊý¾Ý£¬Èç¹û¶ÓÁÐΪ¿Õ£¬·µ»Ø-1
int deQueue(intQueue &iq);

mqueue.cpp

#include "mqueue.h"

// 函数queueEmpty:判断队列iq是否为空
// 参数:iq-整数队列
// 返回值:true-队列iq为空,false-iq不为空
bool queueEmpty(intQueue iq)
{
    // 请在此添加代码,补全函数queueEmpty
    /********** Begin *********/ 
    return (listLength(iq) == 0);

    /********** End **********/
}

// 函数enQueue:将整数num入列到iq
// 参数:iq-整数队列,传引用,入列有可能改变队列头指针,num-入列的整数
// 返回值:无,只要还有内存,入列总会成功
void enQueue(intQueue &iq, int num)
{
    // 请在此添加代码,补全函数enQueue
    /********** Begin *********/
    node *t=new node;
    t->data=num;
    t->next=NULL;
    // 结点插入到尾部
    iq = insertTail(iq,t);
    /********** End **********/
}

// 函数deQueue:出列
// 参数:iq-整数队列,传引用,出列有可能改变队列头指针
// 返回值:出列结点的数据,如果队列为空,返回-1
int deQueue(intQueue &iq)
{
    // 请在此添加代码,补全函数deQueue
    /********** Begin *********/
    int n = iq->data;
    // 删除队列头结点(出列)
    iq = delAt(iq,0);
    // 返回出列数据
    return n;

    /********** End **********/
}

test.cpp

#include "mqueue.h"

int main()
{
	intQueue iq=NULL; //ÉùÃ÷¶ÓÁÐiq£¬²¢³õʼ»¯Îª¿Õ¶ÓÁУ¨¿ÕÏßÐÔ±í£©
	int command; //ÊäÈëÖ¸Á1-ÈëÁУ¬0-³öÁУ¬-1-Í˳ö£¬ÆäËü-·Ç·¨²Ù×÷
	int n;
	//ÊäÈëÖ¸Áî
	cin>>command;
	while(command!=-1)
	{
		switch(command) 
		{
		case 0:
			if(!queueEmpty(iq))
			{//¶ÓÁзǿÕ
				n = deQueue(iq); //³öÁÐ
				cout<<n<<endl; //Êä³ö³öÁеÄÖµ
			}
			else
				cout<<"Queue empty"<<endl;
			break;
		case 1:
			cin>>n; //ÊäÈëÒªÈëÁеÄÊý¾Ý
			enQueue(iq,n);
			cout<<"enqueue "<<n<<endl;
			break;
		default:;
		}
		cin>>command;//ÊäÈëÏÂÒ»ÌõÖ¸Áî
	}
	//ɾ³ý¶ÓÁÐ
	delList(iq);

	return 0;
}

线性表应用三:集合

任务描述

本关任务:使用线性表实现集合的表示及操作。具体需要补全三个函数:计算集合并集的 unionSet 函数、计算集合交集的 intersection 函数和向集合中添加元素的 addElement 函数。

相关知识

集合
集合是数学中一个基本概念,它是集合论的研究对象。朴素集合论中,集合的定义就是“一堆东西”,集合里的“东西”,称为元素。

下面介绍几个集合的知识点:

  • 集合中的元素是无序的,对于任意的集合S1和S2,S1=S2当且仅当对于任意的对象a,都有若a∈S1,则a∈S2;若a∈S2,则a∈S1;
  • 集合中的元素互不相同,空集合是没有任何元素的集合;
  • 集合的并集定义为:A∪B=x∣x∈A或x∈B。例如,A={1,3,5},B={1,2,5} ,则A∪B= {1,2,3,5} ;
  • 集合的交集定义为:A∩B=x∣x∈A且x∈B。例如, A= {1,3,5},B={1,2,5} ,则A∩B= {1,5} 。

接下来首先声明结构类型:

// 定义结点结构
struct node
{
    int data;     // 数据域
    node * next;     // 指针域,指向下一个结点
};

typedef node * intSet; // 定义类型别名,intSet 即相当于 node*
上述结构类型的声明中定义 intSet 是为了使程序的可读性更好一些。因为本关是用线性表实现集合,而访问一个线性表其实只需要一个链表头指针就可以了, intSet 实际上就是node*类型,所以后面可以这样声明集合 a :

intSet a=NULL;     // 声明集合 a,并初始化为空集合(空线性表)

编程要求

在右侧编辑器中的Begin-End之间补充代码,完成 unionSet、intersection 、addElement 三个函数,以实现集合的三个功能。具体要求如下:

  • 函数 unionSet 计算并返回集合 a 和 b 的并集。参数 a 和 b 是两个集合,返回值为 a 和 b 的并集。

  • 函数 intersection 计算并返回集合 a 和 b 的交集。参数 a 和 b 是两个集合,返回值为 a 和 b 的交集。

  • 函数 addElement 将元素 num 加入到集合 is 中,如果 is 中已经存在 num 了,则不需要加入,不存在则加入。参数
    is 是一个集合,num 是要加入到 is 中的元素。

    LinearList.h

#include <iostream>
using namespace std;

//¶¨Òå½áµã½á¹¹
struct node
{
	int data;  //Êý¾ÝÓò
	node * next;  //Ö¸ÕëÓò,Ö¸ÏòÏÂÒ»¸ö½áµã
};

//º¯ÊýlistSort£ºÁ´±íÅÅÐò£¨ÎªÁËÊä³ö½á¹ûΨһ£©
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
//·µ»ØÖµ£ºÅÅÐòºóµÄÁ´±í
node * listSort(node *h);
//º¯ÊýlistLength£º¼ÆËã²¢·µ»ØÁ´±íµÄ³¤¶È
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
//·µ»ØÖµ£ºÁ´±í³¤¶È
int listLength(node * h);
//º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n);
//º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i);
//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num);
//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t);
//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t);
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h);
//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t);
//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h);

LinearList.cpp

#include "linearList.h"

//º¯ÊýdelList£ºÉ¾³ýÁ´±í£¬ÊÍ·Å¿Õ¼ä
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void delList(node *h)
{
	node *p=h; //Ö¸ÕëpÖ¸ÏòÍ·½áµã£¬µÚÒ»¸öҪɾ³ýµÄ½áµã
	while(p) //Õâ¸ö½áµãÊÇ´æÔÚµÄ
	{
		h = h->next; //Í·Ö¸ÕëhÖ¸ÏòÏÂÒ»¸ö½áµã£¨ÏÂÒ»¸ö½áµãµÄµØÖ·´æÔÚµ±Ç°½áµãµÄÖ¸ÕëÓòÖУ¬¼´h->nextÖÐ
		delete p; //ɾ³ýpÖ¸ÏòµÄ½áµã
		p = h; //pÖ¸Ïòµ±Ç°µÄÍ·½áµã£¬¼´ÏÂÒ»¸öҪɾ³ýµÄ½áµã
	}
}
//º¯ÊýprintList£ºÊä³öÁ´±í£¬Ã¿¸öÊý¾ÝÖ®¼äÓÃÒ»¸ö¿Õ¸ñ¸ô¿ª
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
void printList(node *h)
{
	cout<<"List:"; 
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ£¬ÔòÊä³ö¸Ã½áµãµÄÊý¾Ý
		cout<<" "<<h->data;  //Êä³ö½áµãÊý¾Ý
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	cout<<endl; //Êä³ö»»Ðзû
}

//º¯ÊýinsertTail£ºÁ´±íβ²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node *insertTail(node *h, node *t)
{
	if(h==NULL) //¿ÕÁ´±íµ¥¶À´¦Àí
	{
		t->next=NULL; //Á´±íβָÕëÖÃΪNULL
		return t; //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
	}
	//·Ç¿ÕÁ´±íµÄÇé¿ö
	node *p=h;
	//ÈÃpÖ¸Ïò×îºóÒ»¸ö½áµã
	while(p->next)
		p=p->next;
	p->next = t; //ÈÃ×îºóÒ»¸ö½áµãµÄÖ¸ÕëÓòÖ¸Ïò½áµãt
	t->next=NULL; //Á´±íβָÕëÖÃΪNULL
	return h;  //·µ»ØµÚÒ»¸ö½áµãµÄµØÖ·£¨¼´Á´±íÍ·Ö¸Õ룩
}

//º¯ÊýinsertHead£ºÁ´±íÍ·²¿²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertHead(node *h, node *t)
{
	t->next=h;
	return t;
}

//º¯ÊýinsertSort£ºÁ´±íÅÅÐò²åÈë
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬t-Ö¸ÏòÒª²åÈëµÄ½áµã
//·µ»ØÖµ£º²åÈë½áµãºóÁ´±íµÄÊ×½áµãµØÖ·
node * insertSort(node *h, node *t)
{
	node *p=NULL,*q=h; //¶¨Î»µÚÒ»¸ö²åÈëµã£ºÁ´Ê×
	while(q && q->data<t->data) //²éÕÒ²åÈëµã
	{//Á½¸öÖ¸Õë²¢ÐкóÒÆ
		p=q;
		q=q->next;
	}
	if(p==NULL) //²åÈëÁ´Ê×
	{
		t->next = h;
		return t;
	}
	if(q==NULL) //²åÈëÁ´Î²
	{
		p->next = t;
		t->next = NULL;
		return h;
	}
	//²åÈëp¡¢qÖ®¼ä
	t->next=q;
	p->next=t;
	return h;
}

//º¯Êýsearch£ºÔÚÁ´±íÖвéÕÒ°üº¬Êý¾ÝnumµÄ½áµã
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬num-Òª²éÕÒµÄÊý¾Ý
//·µ»ØÖµ£ºÕÒµ½ÁË·µ»Ø¸Ã½áµãµÄµØÖ·£¬·ñÔò·µ»ØNULL
node * search(node * h, int num)
{
	while(h)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(h->data==num)
			return h;
		h=h->next;  //½«¸Ã½áµãµÄÖ¸ÕëÓò¸³Öµ¸øh£¬h¾ÍÖ¸ÏòÁËÏÂÒ»¸ö½áµã
	}
	return NULL; //ûÕÒµ½°üº¬numµÄ½áµã
}

//º¯ÊýdelAt£ºÉ¾³ýÁ´±íÖÐÐòºÅΪiµÄ½áµã£¬Èç¹ûiÊÇ·Ç·¨ÐòºÅÔò²»×ö²Ù×÷
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬i-Ҫɾ³ý½áµãµÄÐòºÅ
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delAt(node * h, int i)
{
	if(i<0) //ÐòºÅ·Ç·¨£¬²»É¾³ý
		return h;
	node *p=NULL, *q = h; // ¶¨Î»É¾³ý½áµã£¬ÊÔͼÈÃqÖ¸ÏòҪɾ³ý½áµã£¬pÖ¸ÏòÆäÇ°ÃæµÄ½áµã
	for(int k=0;k<i;k++)
	{
		if(q->next==NULL) //ºóÃæûÓнáµãÁË£¬ÐòºÅ·Ç·¨
			return h;
		p=q;
		q=q->next;
	}
	if(p) //pÖ¸ÏòµÄ½áµã´æÔÚ£¬²»ÊÇɾ³ýÊ×½áµã
	{
		//ɾ³ýqÖ¸ÏòµÄ½áµã£¬ÈÃpÖ¸Ïò½áµãµÄÖ¸ÕëÓòÖ¸ÏòqµÄºóÐø½áµã
		p->next = q->next;
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
	else //ɾ³ýÊ×½áµã
	{
		h = q->next; //ÏÂÒ»¸ö½áµã³ÉÁËÊ×½áµã
		//ÊÍ·Å¿Õ¼ä
		delete q;
		return h;
	}
}

//º¯ÊýdelHas£ºÉ¾³ýÁ´±íÖÐdataΪnµÄ½áµã£¬Èç¹ûÓжà¸öÕâÑùµÄ½áµã£¬Ö»É¾³ýµÚÒ»¸ö
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õ룬n-½áµã°üº¬µÄÊý¾Ý
//·µ»ØÖµ£ºÉ¾³ý½áÊøºóÁ´±íÊ×½áµãµØÖ·
node * delHas(node * h, int n)
{
	node *p=NULL, *q=h; //pΪҪɾ³ý½áµãµÄÇ°½áµã£¬qÖ¸ÏòҪɾ³ý½áµã
	while(q)
	{//hΪÕ棬¼´hÖ¸ÏòµÄ½áµã´æÔÚ
		if(q->data==n)
			break; //ÕÒµ½ÁË
		if(q->next==NULL)//ºóÃæûÓнáµãÁË£¬Ã»ÓнáµãÂú×ãÌõ¼þ
			return h; //²»É¾³ý£¬Ö±½Ó·µ»Ø
		//¼ÌÐøÍùºóÕÒ£¬Á½¸öÖ¸ÕëÒ»ÆðºóÒÆ
		p=q;
		q=q->next;
	}
	//ɾ³ýqÖ¸ÏòµÄ½áµã
	if(p==NULL)//ɾ³ýÍ·½áµã
	{
		h=q->next;//ÏÂÒ»¸ö½áµã±ä³ÉÍ·½áµã
		delete q;//ɾ³ý½áµã
		return h;
	}
	//²»ÊÇÍ·½áµã
	p->next=q->next;//°ÑqÖ¸Ïò½áµãµÄÖ¸ÕëÓò£¨qºóÃæ½áµãµÄµØÖ·£©¸³Öµ¸øpÖ¸Ïò½áµãµÄÖ¸ÕëÓò
	return h;
}

//º¯ÊýlistLength£º¼ÆËã²¢·µ»ØÁ´±íµÄ³¤¶È
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
//·µ»ØÖµ£ºÁ´±í³¤¶È
int listLength(node * h)
{
	int n=0;
	while(h)
	{
		n++;
		h=h->next;
	}
	return n;
}
//º¯ÊýlistSort£ºÁ´±íÅÅÐò£¨ÎªÁËÊä³ö½á¹ûΨһ£©
//²ÎÊý£ºh-Á´±íÍ·Ö¸Õë
//·µ»ØÖµ£ºÅÅÐòºóµÄÁ´±í
node * listSort(node *h)
{
	node *p=NULL, *t=h;
	while(t)
	{
		h=h->next;
		t->next=NULL;
		p=insertSort(p,t);
		t=h;
	}
	return p;
}


mset.h

#include "linearList.h"

typedef node * intSet;  // ¶¨ÒåÀàÐͱðÃû£¬intSet¼´Ï൱ÓÚnode*

// º¯ÊýunionSet£ºÇ󼯺ÏaºÍbµÄ²¢¼¯
// ²ÎÊý£ºa-¼¯ºÏ£¬b-¼¯ºÏ
// ·µ»ØÖµ£º¼¯ºÏ£¨¼¯ºÏaºÍbµÄ²¢¼¯£©
intSet unionSet(intSet a, intSet b);

// º¯Êýintersection£ºÇ󼯺ÏaºÍbµÄ½»¼¯
// ²ÎÊý£ºa-¼¯ºÏ£¬b-¼¯ºÏ
// ·µ»ØÖµ£º¼¯ºÏ£¨¼¯ºÏaºÍbµÄ½»¼¯£©
intSet intersection(intSet a, intSet b);

// º¯ÊýaddElement£ºÔÚ¼¯ºÏisÖÐÔö¼ÓÔªËØnum
// ²ÎÊý£ºis-¼¯ºÏ£¬num-ÒªÔö¼ÓµÄÔªËØ
// ·µ»ØÖµ£ºÎÞ
void addElement(intSet &is, int num);

mset.cpp

#include "mset.h"

// 函数unionSet:求集合a和b的并集
// 参数:a-集合,b-集合
// 返回值:集合(集合a和b的并集)
intSet unionSet(intSet a, intSet b)
{
    // 请在此添加代码,补全函数unionSet
    /********** Begin *********/
    intSet c=NULL;
    // 把a中每一个元素加入c中
    node *p=a;
    while(p)
    {
        addElement(c,p->data);
        p=p->next;
    }
    // 把b中每一个元素加入c中
    p=b;
    while(p)
    {
        addElement(c,p->data);
        p=p->next;
    }
    return c;



    /********** End **********/
}

// 函数intersection:求集合a和b的交集
// 参数:a-集合,b-集合
// 返回值:集合(集合a和b的交集)
intSet intersection(intSet a, intSet b)
{
    // 请在此添加代码,补全函数intersection
    /********** Begin *********/
    intSet c=NULL;
    // 查看a中每一个元素
    node *p=a;
    while(p)
    {
        if(search(b,p->data))
        {// 也在b中,则选入集合c
            addElement(c,p->data);
        }
        p=p->next;
    }
    return c;

    /********** End **********/
}

// 函数addElement:在集合is中增加元素num
// 参数:is-集合,num-要增加的元素
// 返回值:无
void addElement(intSet &is, int num)
{
    // 请在此添加代码,补全函数addElement
    /********** Begin *********/
    node *p=search(is,num);
    if(p!=NULL)
        return;
    
    p=new node;
    p->data = num;
    p->next = NULL;
    is = insertHead(is,p);


    /********** End **********/
}

test.cpp

#include "mset.h"

int main()
{
	//ÉùÃ÷4¸ö¿Õ¼¯ºÏ
	intSet a=NULL,b=NULL,c=NULL,d=NULL;
	int n,num,i;
	//ÊäÈ뼯ºÏa
	cin>>n;
	for(i=0;i<n;i++)
	{
		cin>>num;
		addElement(a,num);
	}
	//ÊäÈ뼯ºÏb
	cin>>n;
	for(i=0;i<n;i++)
	{
		cin>>num;
		addElement(b,num);
	}
	//¼ÆË㼯ºÏ½»¼¯
	c=intersection(a,b);
	//¼ÆËã²¢¼¯
	d=unionSet(a,b);
	//µ÷Õû¼¯ºÏc¡¢dÖÐÔªËصÄ˳Ðò
	c = listSort(c);
	d = listSort(d);
	//Êä³ö½á¹û
	printList(c);
	printList(d);
	//ɾ³ý½áµã£¬ÊÍ·Å¿Õ¼ä
	delList(a);
	delList(b);
	delList(c);
	delList(d);

	return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C++中的线性表可以使用数组或链表来实现。数组实现的线性表具有随机访问的特点,而链表实现的线性表则具有插入和删除元素的高效性。 以下是C++中数组实现线性表的基本操作: 1.初始化线性表 ```c++ const int MAXSIZE = 100; // 线性表的最大长度 typedef struct { int data[MAXSIZE]; // 存储线性表元素的数组 int length; // 线性表的当前长度 } SqList; void InitList(SqList &L) { for (int i = 0; i < MAXSIZE; i++) { L.data[i] = 0; } L.length = 0; } ``` 2.插入元素 ```c++ bool ListInsert(SqList &L, int i, int e) { if (i < 1 || i > L.length + 1) { return false; } if (L.length >= MAXSIZE) { return false; } for (int j = L.length; j >= i; j--) { L.data[j] = L.data[j - 1]; } L.data[i - 1] = e; L.length++; return true; } ``` 3.删除元素 ```c++ bool ListDelete(SqList &L, int i, int &e) { if (i < 1 || i > L.length) { return false; } e = L.data[i - 1]; for (int j = i; j < L.length; j++) { L.data[j - 1] = L.data[j]; } L.length--; return true; } ``` 4.查找元素 ```c++ int LocateElem(SqList L, int e) { for (int i = 0; i < L.length; i++) { if (L.data[i] == e) { return i + 1; } } return 0; } ``` 以下是C++中链表实现线性表的基本操作: 1.定义链表节点 ```c++ typedef struct LNode { int data; struct LNode *next; } LNode, *LinkList; ``` 2.初始化链表 ```c++ void InitList(LinkList &L) { L = (LNode*)malloc(sizeof(LNode)); L->next = NULL; } ``` 3.插入元素 ```c++ bool ListInsert(LinkList &L, int i, int e) { if (i < 1) { return false; } LNode *p = L; int j = 0; while (p && j < i - 1) { p = p->next; j++; } if (!p) { return false; } LNode *s = (LNode*)malloc(sizeof(LNode)); s->data = e; s->next = p->next; p->next = s; return true; } ``` 4.删除元素 ```c++ bool ListDelete(LinkList &L, int i, int &e) { if (i < 1) { return false; } LNode *p = L; int j = 0; while (p->next && j < i - 1) { p = p->next; j++; } if (!(p->next) || j > i - 1) { return false; } LNode *q = p->next; e = q->data; p->next = q->next; free(q); return true; } ``` 5.查找元素 ```c++ LNode* GetElem(LinkList L, int i) { if (i < 0) { return NULL; } LNode *p = L; int j = 0; while (p && j < i) { p = p->next; j++; } return p; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值