《啊哈算法》第二章 栈,队列,链表

参考:《啊哈算法》
嗯,抄代码的意义在于你能不能抄正确!
嗯,我又开始了新的学习,任务没有完成哪里还有时间吃饭?不逼逼自己不知道自己的潜力究竟有多大!

本章的基本数据结构都是使用的顺序表实现的!不管那么多,动手才是硬道理,先理解原理才是硬道理。虽然上学期已经学过这个了,但是,。,。,。坚持做自己不想做的,得到别人得不到的。

1,队列。(和标题顺序不符呀)对列就是先进先出。(FIFO)
问题:序列631758924,删除对头,次对头放到队尾,重复操作直到队为空,求删除数字序列(即QQ号)
数组模拟,一个head,一个tail.head++删除头,tail++尾部插入
成功解密QQ号
(注意:判断队空的条件是队头等于队尾。技巧:通常把tail设到队尾的下一位,方便直接添加,比较直观。否则,还要先tail++一次

#include<iostream>
using namespace std;
const int N=100;
int main()
{
    int a[N]={6,3,1,7,5,8,9,2,4},head,tail;
    head=0;
    tail=9;
    //while(head<tail)
    while(a[head]){
        cout<<a[head]<<ends;//输出队头
        head++;//前进到下一位
        a[tail]=a[head];//送到对尾部
        head++;//后移
        tail++;//后移
    }
    cout<<endl;
    return 0;
}

结构体封装的队列(队列三个基本元素,数据内容,队首,队尾)

#include <iostream>
using namespace std;
const int N=100;
typedef struct Que {
    char  data[N];
    int head;
    int tail;
};
int main() {
    cout<<"Please enter the QQ :"<<endl;
    Que q;
    char c;
    int i=0;
    while(cin>>c) {
        q.data[i++]=c;
    }
    int n=i;//i就是总数据数
    q.head=0;
    q.tail=n;
    while(q.head<q.tail) {
        cout<<q.data[q.head]<<ends;
        q.head++;
        q.data[q.tail]=q.data[q.head];
        q.head++;
        q.tail++;
    }
    cout<<endl;
    return 0;
}

嗯,再来一发,STL封装的队列
进队:push()
出队:pop()
队首:.front()
队尾:.back()

#include<iostream>
#include <queue>
using namespace std;
int main()
{
    queue<char> QQ;
    cout<<"Please enter the QQ:"<<endl;
    char c;
    while(cin>>c){
        QQ.push(c);
    }
    while(!QQ.empty()){
        cout<<QQ.front()<<ends;
        QQ.pop();
        QQ.push(QQ.front());
        QQ.pop();
    }
    return 0;
}

2,栈,栈规定只能在一端进行操作,因此栈为后进先出,(FILO)
顺序表表示的话,就是一个栈顶top,top++,top–进出栈
问题:判断字符串是不是回文串

#include<iostream>
using namespace std;
const int N=10;
char str[N];
int main() {
    char c;
    int i=0;
    while(cin>>c) {
        str[i++]=c;
    }
    int n=i;
    int mid=n/2-1;
    int top=0;
    for(int i=0; i<=mid; i++) {
        str[top++]=str[i];
    }
    top=top-1;
    int next;
    if(n%2==0) {
        next=mid+1;
    } else {
        next=mid+2;
    }
    int flag=1;
    for(int i=next; i<n; i++) {
        if(str[i]!=str[top--]) {
                flag=0;
            break;
        }
    }
    if(flag){
        cout<<"YES"<<endl;
    }
    else {
        cout<<"NO"<<endl;
    }
    return 0;
}

(发现个问题,自己看了书,再自己弄一遍的过程中,分析的时候简直是移步到位,越来越多的技巧,比如使用寄存器,计数器,怎么往逻辑外传逻辑内得到的参数值,再比如这里找中点和另一半的起始位置简直了)

STL stack的用法,push,pop,.top()

判断回文串嘛,怎么需要用栈尼,栈用在括号匹配才是硬道理,没学之前处理括号匹配实在是繁杂。
下面是简单的判断回文串。(以前看舍友的代码,有些知识,真的是会过目不忘)

#include<iostream>
#include <stack>
using namespace std;
#define N 100
char str[N];
int main() {
    char c;
    int i=0;
    while(cin>>c) {
        str[i++]=c;
    }
    int n=i;
    bool flag=true;
    for(int i=0,j=n-1;i<=j; i++,j--) {
        if(str[i]!=str[j]) {
            flag=false ;
            break;
        }
    }
    if(flag) {
        cout<<"YES"<<endl;
    } else {
        cout<<"NO"<<endl;
    }
    return 0;
}

3,链表。之前看过谭叔的书。最后一章就是讲得链表,当时也是抄了几遍代码。思维有点混乱。
提到链表就不得不说起指针,指针就是用来存放内存地址的,常用*号表示。
提到链表就不得不说增删改查,于是用于增加的动态申请就出来了。
下面是对*在C/C++中用途的总结:

  1. *用作乘法符号。
  2. *声明一个指针。eg:int *p
  3. *间接运算符(解引用)

    指针的范例

#include<cstdio>
#include <cstdlib>
int main()
{
    int *p;
    p=(int*)malloc(sizeof(int));
    *p=10;
    printf("%d\n",*p);
    return 0;
}

(mallooc函数在stdlib里面,free释放)
嗯,简单来说使用指针的步骤有两步,第一是定义指针变量;第二就是给指针变量填充内容(赋值),值可以是地址&a,也可是*p=a的形式
下面的代码与上一段程序实现相同的内容:

#include <cstdio>
#include <cstdlib>
int main()
{
    int *p;
    int a;
    scanf("%d",&a);
    p=&a;
    printf("%d\n",*p);
    return 0;
}

当然C++中是使用new 来动态动态申请空间,delete进行释放。

#include <iostream>
using namespace std;
int main()
{
    int *p;
    p=new int ;
    *p=10;
    cout<<*p<<endl;
    delete p;
    return 0;
}

下面的程序是一定错误的,禁忌,因为没有申请分配空间,仅仅是定义了一个变量

#include <iostream>
using namespace std;
int main() {
    int *p;
    *p=10;
    cout<<*p<<endl;
    return 0;
}

简单的建立链表

#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct Node { //不要混淆在这里写成*Node,节点类型一般不设为指针
    int data;
    struct Node *next;//自引用,定义了结点的内容。
};
int main() {
    int T;
    Node *p,*q,*head;
    head=NULL;
    cin>>T;
    while(T--) {
        int a;
        cin>>a;
        p=(Node*)malloc(sizeof(Node));
        p->data=a;
        p->next=NULL;
        if(head==NULL) {//这里以前一直不是很懂,终于明白了
            head=p;

        } else {
            q->next=p;
        }
        q=p;
    }
    p=head;
    while(p!=NULL) {
        cout<<p->data<<ends;
        p=p->next;
    }
    cout<<endl;
}

链表添加和删除(排除在第一位添加和删除的情况)

#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct Node { //不要混淆在这里写成*Node,节点类型一般不设为指针
    int data;
    struct Node *next;//自引用,定义了结点的内容。
};
int main() {
    int T;
    Node *p,*q,*head;
    head=NULL;
    cout<<"Please enter the amount of list node:"<<endl;
    cin>>T;
    cout<<"Please enter the list :(ctrl+z to end)"<<endl;
    while(T--) {
        int a;
        cin>>a;
        p=(Node*)malloc(sizeof(Node));
        p->data=a;
        p->next=NULL;
        if(head==NULL) {//这里以前一直不是很懂,终于明白了
            head=p;

        } else {
            q->next=p;
        }
        q=p;
    }
    p=head;
    cout<<"You have created the list:"<<endl;
    while(p!=NULL) {
        cout<<p->data<<ends;
        p=p->next;
    }

    //添加数据
    cout<<"\nPlease enter the number you want to add"<<endl;
    int b;
    cin>>b;
    p=(Node*)malloc(sizeof(Node));
    p->data=b;
    p->next=NULL;
    Node *it;
    it=head;
    while(it!=NULL) {
        if(it->next!=NULL&&it->next->data>b) {//妙,先看看下一项,不过这里好像健壮性不强,要是在第一个位置就要插入怎么办?
            p->next=it->next;
            it->next=p;
            break;//插入结束
        }
        it=it->next;
    }
    cout<<"The new list:"<<endl;
    p=head;
    while(p!=NULL) {
        cout<<p->data<<ends;
        p=p->next;
    }
    cout<<endl;

    //删除数据
    cout<<"Please enter the number which you want to delete :"<<endl;
    cin>>b;
    it=head;
    while(it!=NULL) {
        if(it->next!=NULL&&it->next->data==b) {
            it->next=it->next->next;
            break;
        }
        it=it->next;
    }
    cout<<"The new list:"<<endl;
    p=head;
    while(p!=NULL) {
        cout<<p->data<<ends;
        p=p->next;
    }
    cout<<endl;
    return 0;
}

执行:
这里写图片描述

4,嗯,最后的模拟链表简直是第一次看见,没有多大作用,用一个数组记录数据,再用一个数组记录数据数组右边的数据存在哪一个位置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值