数据结构与算法

1.顺序队列(环状)

/*1.5 顺序队列

	bool EnQueue(const T item)	//1.5-a.	入队操作,判断队列是否为满	
	bool DeQueue(T& item)		//1.5-b.	返回队头元素,并删除该元素,判断队列是否为空	
	bool GetFront(T& item)		//1.5-c.	返回队头元素,但不删除,判断队列是否为空】

*/
#include <iostream>
using namespace std;

template <class T>
class ArrayQueue {
private:
    int maxSize; //队列最大容量
    int front;
    int rear;
    int* queue;

public:
    ArrayQueue(int size)
    {
        maxSize = size + 1;
        queue = new T[maxSize];
        front = rear = 0;
    }
    ~ArrayQueue()
    {
        delete[] queue;
    }

    void Clear()
    {
        front = rear;
    }

    /*
	TODO:1.5-a.入队操作,判断队列是否为满,如果队列已满,则输出打印cout << "队列已满,溢出" << endl;,返回false。
	否则,将值item进行入队操作。并返回true
	返回值说明:入队成功,返回true,否则返回false
	 */
    bool EnQueue(const T item)
    {
            if(this->IsFull()){
            return false;
        }
        queue[rear] = item;
        rear = (rear + 1) % maxSize;
        return true;
    }
    /*
	TODO:1.5-b.返回队头元素,并删除该元素,判断队列是否为空
	如果队列为空,则输出打印cout << "队列为空" << endl;并返回false。
	否则将队列头元素取出并赋值给item变量并删除该元素,返回true
	返回值说明:成功获取队头元素返回true,否则返回false
	 */
    bool DeQueue(T& item)
    {
            if(this->IsEmpty()){
            return false;
        }
        item = queue[front];
        front = (front + 1) % maxSize;
        return true;

    }
    /*
	TODO:1.5-c.	返回队头元素,但不删除,判断队列是否为空
	如果队列为空,则打印cout << "队列为空" << endl;并返回false。
	否则取出队头元素赋值给item,返回true。
	返回值说明:成功获取队头元素,返回true,否则返回false
	 */
    bool GetFront(T& item)
    {
           if(this->IsEmpty()){
            return false;
        }
        item = queue[front];
        return true;

    }

    bool IsEmpty()
    {
        if (front == rear) {
            cout << "队列为空" << endl;
            return true;
        } else {
            return false;
        }
    }
    bool IsFull()
    {
        if ((rear + 1) % maxSize == front) {
            cout << "队列已满,溢出" << endl;
            return true;
        } else {
            return false;
        }
    }
};

int main()
{
    int maxsize = 0, iNum = 0, temp1 = 0, temp2 = 0, temp3 = 0;
    cin >> maxsize >> iNum >> temp1;
    ArrayQueue<int> aq(maxsize);
    for (int i = 0; i < iNum; i++) {
        aq.EnQueue(i * 3);
    }
    aq.EnQueue(temp1);
    aq.DeQueue(temp2);
    cout << "出队:" << temp2 << endl;
    aq.GetFront(temp3);
    cout << "读取队头元素:" << temp3 << endl;
    return 0;
}

2.链式队列(结构体链表)

#include <iostream>
using namespace std;			// 标准库包含在命名空间std中

// 结点类模板
/*
TODO:定义一个模板结构体,包含:一个模板类型变量data存数据,
一个该结构体指针类型变量next作为后继结点指针,一个无参构造函数,
一个带数据和指针形参的构造函数
*/
template <class ElemType>
struct Node
{
    ElemType data;
    struct Node<ElemType> *next;
	Node()
// 操作结果:构造指针域为空的结点
	{
	data = NULL;
	next = NULL;
}
	Node(ElemType item, Node<ElemType> *link)
// 操作结果:构造一个数据域为item和指针域为link的结点
{
	data = item;
	next = link;
}

};

// 结点类模板的实现部分

/*
TODO:定义无参构造函数
函数功能:初始化结构体成员,next置为空
参数说明:无
返回值说明:无
*/

/*
TODO:定义带参构造函数
函数功能:使用形参初始化结构体成员.
参数说明:item-数据,link-后继指针
返回值说明:无
*/


// 链队列类模板

template<class ElemType>
class LinkQueue
{
	protected:
		int count;
		Node<ElemType> *front;
		Node<ElemType> *rear;
/*
TODO:定义protected类型成员:两个模板类Node指针变量front, rear存队首队尾,
int型变量count存元素个数
*/

public:
//  抽象数据类型方法声明及重载编译系统默认方法声明:
        LinkQueue();									// 无参数的构造函数模板
        virtual ~LinkQueue();							// 析构函数模板
        bool Empty() const;								// 判断队列是否为空
        void Clear();									// 将队列清空
        bool OutQueue(ElemType &e);						// 出队操作
        bool InQueue(const ElemType &e);				// 入队操作
};

// 链队列类模板的实现部分

/*
TODO:构造一个空队列
函数功能:初始化类成员,生成头结点,空队列元素个数为0
参数说明:无
返回值说明:无
*/
template<class ElemType>
LinkQueue<ElemType>::LinkQueue()
// 操作结果:构造一个空队列
{
	count = 0;
	front = rear = NULL;
}

/*
TODO:完成定义析构函数的功能
函数功能:调用函数释放存储空间.
参数说明:无
返回值说明:无
*/
template<class ElemType>
LinkQueue<ElemType>::~LinkQueue()
// 操作结果:销毁队列
{
	Clear();
}

/*
TODO:判断队列是否为空
函数功能:判断队列是否为空;如果队列中元素个数为0,则返回true;否则返回false.
参数说明:无
返回值说明:如果队列为空则返回true,否则返回false
*/
template<class ElemType>
bool LinkQueue<ElemType>::Empty() const
// 操作结果:如队列为空,则返回true,否则返回false
{
	if (count == 0)
	return true;
	else return false;

}

/*
TODO:清空队列
函数功能:当队列不空时循环调用函数出队列.
参数说明:无
返回值说明:无
*/
template<class ElemType>
void LinkQueue<ElemType>::Clear()
// 操作结果:清空队列
{
	while (front !=NULL)
	{
		rear = front;
		front = front->next;
		delete rear;
	}
	rear = NULL;
	count = 0;

}

/*
TODO:完成获取出队列的第一元素功能
函数功能:如果队列空直接返回失败,否则利用临时变量取出队头元素,释放出队的结点,
个数减少1.
参数说明:e-存放出队列的第一个元素的变量
返回值说明:如队列非空,用e返回出队列第一个的元素,返回true,否则返回false
*/
template<class ElemType>
bool LinkQueue<ElemType>::OutQueue(ElemType &e)
// 操作结果:如果队列非空,那么删除队头元素,并用e返回其值,返回true,
//	否则返回false,
{
	Node <ElemType> *temp;
	if (count == 0)
	{
		return false;
	}
	else {
		e = front->data;
		temp = front;
		front = front->next;
		delete temp;
		if (front == NULL)
		{
			rear == NULL;
		}
		count--;
		return true;
	}

}

/*
TODO:完成将一个元素值插进队列的功能
函数功能:生成新结点,新结点追加在队尾,rear指向新队尾,元素个数自加1.
参数说明:e-存放进队列的元素的变量
返回值说明:返回true
*/
template<class ElemType>
bool LinkQueue<ElemType>::InQueue(const ElemType &e)
// 操作结果:插入元素e为新的队尾,返回true
{
	if(rear == NULL){
		front = rear = new Node<ElemType> (e,NULL);
	}
	else{
		rear->next = new Node<ElemType> (e,NULL);
		rear = rear->next;

	}
	count ++;
	return true;

}

template <class ElemType>
void Show(const ElemType &e)
// 操作结果: 显示数据元素
{
    cout << e << "  ";				// 输出e
}

int  main(void)
{
    LinkQueue<double> sa;
    double x;
    for (int i = 0; i < 6; i++) {
        cin >> x;
        sa.InQueue(x);
        /*
        TODO:sa调用InQueue传参x进队列
        */
    }
    cout << "out queue:";
    while (sa.OutQueue(x)) {
        cout << x << " ";
    }

    return 0;
}

3.KMP算法

/*1.7-b,c KMP模式匹配算法

	//1.7-b.	计算字符串特征向量的算法,返回特征向量的数组。
	int* next(string P)

	//1.7-c.	KMP模式匹配算法,返回子串第一次出现的位置,若不存在,返回-1
	int KMPStrMatching(string T, string P, int* N, int startIndex)

*/
#include <assert.h>
#include <iostream>
#include <string.h>

using namespace std;

/*
TODO:计算字符串p的特征向量的算法,返回特征向量的数组。
功能描述:定义int型变量m,初始值为P的长度;
         调用函数assert传参 m>0 判断;
         定义int型指针变量N,初始化为int型数组,长度为m;
         调用函数assert传参 N != 0 判断;
         N[0]赋值0;
         for循环,循环变量i从1开始到小于m的长度结束,
           定义int型变量k,初始值为N[i - 1]
           while循环,循环条件:k不等于0 并且 P[i]不等于P[k]
                      循环体:N[i] 赋值为 k+1
           while循环结束后,
           如果变量i大于0 并且 P[i]等于P[k] 时,N[i]赋值为k+1,
           否则,N[i]赋值为0
        for循环结束后,返回N
参数说明:P-要计算特征向量的字符串
返回值说明:指向特征向量的指针
 */
int* next(string P)
{
    int m = P.size();
    assert (m > 0);
    int *N = new int[m];
    assert (N!=0);
    N[0] = 0;
    for (int j = 1;j < m;j ++)
    {
        int k = N[j-1];
        while (k > 0&& P[j] !=P[k])
        k = N[k-1];
        if (P[j]==P[k])
        N[j] = k + 1;
        else
        N[j] = 0;
    }
    return N;
}

/*
TODO:KMP模式匹配算法,返回子串第一次出现的位置
功能描述:定义int型变量lastIndex,初始值为T的长度减P的长度;
        如果lastIndex减startIndex 小于 0,返回-1;
        定义int型变量i;定义int型变量j,初始值为0;
        for循环,循环变量i从0开始到小于T的长度结束,
          while循环,循环条件:P[j]不等于T[i] 并且 j大于0,
              循环体:j赋值为N[j - 1]
          while循环结束后,
          如果P[j]等于T[i],j累加1;
          如果j等于P的长度,返回(i - j + 1);
        for循环结束后,返回-1
参数说明:T-原始字符串,P-子串,N-字符串P的特征向量
返回值说明:查找到则返回子串第一次出现的位置;没有查找到,返回-1
*/
int KMPStrMatching(string T, string P, int* N, int startIndex)
{
    int lastIndex = T.size()-P.size();
    if ((lastIndex - startIndex )< 0)
    return (-1);
    int i = startIndex;
    int j = 0;
    while (i < T.size()&&j <P.size()){
        if (P[j] == T[i]){
            i++;
            j++;
        }
        else if (j!=0)
        j = N[j-1];
        else
        i++;
    }
    if (j == P.size())
    return (i-j);
    else
    return (-1);
}

int main()
{
    string p; //要查找的字符串
    string q; //原始字符串
    getline(cin, p);
    getline(cin, q);
    int* N;
    N = next(p);
    for (int i = 0; i < p.length(); i++)
        cout << N[i] << " ";
    cout << endl;
    cout << KMPStrMatching(q, p, N, 0) << endl;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值