6.1-数据结构&算法-堆栈与队列

-----------------
第七课  堆栈与队列
一、数据结构的基本概念
1.逻辑结构
1)集合结构(集):结构中的元素除了同属一个集之外,没有任何联系。
2)线性结构(表):结构中的元素具有一对一的前后关系。
3)树型结构(树):结构中的元素具有一对多的父子关系。
4)网状结构(图):结构中的元素具有多对多的交叉映射关系。
2.物理结构
1)顺序结构(数组):结构中的元素存放在一段连续的地址空间中。随机访问方便,空间利用率低,插入删除不便。
2)链式结构(链式):结构中的元素存放在彼此独立的地址空间中,每个独立的地址空间被称为节点,节点除了保存数据以外,还保存另外一个或几个相关节点的地址。空间利用率高,插入删除方便,随机访问不便。
3.逻辑结构和物理结构的关系
      表    树  图
顺序 数组 顺序树 复  
链式 链表 链式树 合
二、数据结构的基本运算
1.创建与销毁
2.插入与删除
3.获取与修改
4.排序与查找
三、堆栈
1.基本特征:后进先出
2.基本操作:压入(push),弹出(pop)
3.实现要点:初始化空间,栈顶指针,判空判满。
1234
1*9^3+2*9^2+3*9^1+4*9^0 -> 4
123 -> 3
12 -> 2
1 -> 1
 
format.cpp
#include <iostream>
#include <fstream>
using namespace std;
int main (void) {
    ofstream ofs ("format.txt");
    if (! ofs) {
        perror ("打开文件失败");
        return -1;
    }
    ofs << 1234 << ' ' << 56.78 << ' ' << "tarena"
        << '\n';
    ofs.close ();
    ofs.open ("format.txt", ios::app);
    if (! ofs) {
        perror ("打开文件失败");
        return -1;
    }
    ofs << "append_a_line\n";
    ofs.close ();
    ifstream ifs ("format.txt");
    if (! ifs) {
        perror ("打开文件失败");
        return -1;
    }
    int i;
    double d;
    string s1, s2;
    ifs >> i >> d >> s1 >> s2;
    cout << i << ' ' << d << ' ' << s1 << ' '
        << s2 << endl;
    ifs.close ();
    return 0;
}

istack.cpp

#include <iostream>
using namespace std;
// 基于链式表的堆栈
class Stack {
public:
    // 构造过程中初始化为空堆栈
    Stack (void) : m_top (NULL) {}
    // 析构过程中销毁剩余的节点
    ~Stack (void) {
        for (Node* next; m_top; m_top = next) {
            next = m_top->m_next;
            delete m_top;
        }
    }
    // 压入
    void push (int data) {
        /*
        Node* node = new Node;
        node->m_data = data;
        node->m_next = m_top;
        m_top = node;*/
        m_top = new Node (data, m_top);
    }
    // 弹出
    int pop (void) {
        if (empty ())
            throw UnderFlow ();
        int data = m_top->m_data;
        Node* next = m_top->m_next;
        delete m_top;
        m_top = next;
        return data;
    }
    // 判空
    bool empty (void) const {
        return ! m_top;
    }
private:
    // 下溢异常
    class UnderFlow : public exception {
        const char* what (void) const throw () {
            return "堆栈下溢!";
        }
    };
    // 节点
    class Node {
    public:
        Node (int data = 0, Node* next = NULL) :
            m_data (data), m_next (next) {}
        int m_data; // 数据
        Node* m_next; // 后指针
    };
    Node* m_top; // 栈顶
};
int main (void) {
    try {
        Stack stack;
        for (int i = 0; i < 10; ++i)
            stack.push (i);
        while (! stack.empty ())
            cout << stack.pop () << endl;
//        stack.pop ();
    }
    catch (exception& ex) {
        cout << ex.what () << endl;
        return -1;
    }
    return 0;
}

putget.cpp

#include <iostream>
#include <fstream>
using namespace std;
int main (void) {
    ofstream ofs ("putget.txt");
    if (! ofs) {
        perror ("打开文件失败");
        return -1;
    }
    for (char c = ' '; c <= '~'; ++c)
        if (! ofs.put (c)) {
            perror ("写入文件失败");
            return -1;
        }
    ofs.close ();
    ifstream ifs ("putget.txt");
    if (! ifs) {
        perror ("打开文件失败");
        return -1;
    }
    char c;
    while ((c = ifs.get ()) != EOF)
        cout << c;
    cout << endl;
    if (! ifs.eof ()) {
        perror ("读取文件失败");
        return -1;
    }
    ifs.close ();
    return 0;
}

seek.cpp

#include <iostream>
#include <fstream>
using namespace std;
int main (void) {
    fstream fs ("seek.txt", ios::in | ios::out);
    if (! fs) {
        perror ("打开文件失败");
        return -1;
    }
    fs << "0123456789";
    cout << fs.tellp () << endl;
    cout << fs.tellg () << endl;
    fs.seekp (-3, ios::cur);
    fs << "XYZ";
    fs.seekg (4, ios::beg);
    int i;
    fs >> i;
    cout << i << endl;
    cout << fs.tellg () << endl;
    cout << fs.tellp () << endl;
    fs.seekg (-6, ios::end);
    fs << "ABC";
    fs.close ();
    return 0;
}

stack.cpp

#include <iostream>
using namespace std;
// 基于顺序表的堆栈
class Stack {
public:
    // 构造过程中分配内存
    Stack (size_t size = 10) :
        m_array (new int[size]), m_size (size),
        m_top (0) {}
    // 析构过程中释放内存
    ~Stack (void) {
        if (m_array) {
            delete[] m_array;
            m_array = 0;
        }
    }
    // 压入
    void push (int data) {
        if (full ())
            throw OverFlow ();
        m_array[m_top++] = data;
    }
    // 弹出
    int pop (void) {
        if (empty ())
            throw UnderFlow ();
        return m_array[--m_top];
    }
    // 判满
    bool full (void) const {
        return m_top >= m_size;
    }
    // 判空
    bool empty (void) const {
        return ! m_top;
    }
private:
    // 上溢异常
    class OverFlow : public exception {
        const char* what (void) const throw () {
            return "堆栈上溢!";
        }
    };
    // 下溢异常
    class UnderFlow : public exception {
        const char* what (void) const throw () {
            return "堆栈下溢!";
        }
    };
    int* m_array; // 数组
    size_t m_size; // 容量
    size_t m_top; // 栈顶
};
void printb (unsigned int numb, int base) {
    Stack stack (256);
    do {
        stack.push (numb % base);
    }    while (numb /= base);
    while (! stack.empty ()) {
        int digit = stack.pop ();
        if (digit < 10)
            cout << digit;
        else
            cout << char (digit - 10 + 'A');
    }
    cout << endl;
}
int main (void) {
    try {
        Stack stack;
        for (int i = 0; ! stack.full (); ++i)
            stack.push (i);
//        stack.push (0);
        while (! stack.empty ())
            cout << stack.pop () << endl;
//        stack.pop ();
    }
    catch (exception& ex) {
        cout << ex.what () << endl;
        return -1;
    }
    cout << "输入一个整数:" << flush;
    int numb;
    cin >> numb;
    cout << "您想看几进制:" << flush;
    int base;
    cin >> base;
    cout << "结果:";
    printb (numb, base);
    return 0;
}

stream.cpp

#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
#include <sstream>
using namespace std;
int main (void) {
    cout << sqrt (2) << endl;
    cout.precision (10); // 10位有效数字
    cout << sqrt (2) << endl;
    cout << sqrt (2) * 100 << endl;
    cout << setprecision (5) << sqrt (2) << endl
        << sqrt (2) * 100 << endl;
    cout << "当前精度:" << cout.precision ()
        << endl;
    cout << setprecision (2) << 1.24 << ' ' << 1.25
        << ' ' << 1.26 << endl;
    cout << showbase << hex << 127 << endl;
    cout << oct << 127 << endl;
    cout << dec << 127 << endl;
    cout << noshowbase << hex << 127 << dec << endl;
    cout << setw (12) << 127 << 721 << endl;
    cout << setfill ('$') << left << setw (12)
        << 127 << endl;
    cout.precision (10);
    cout.setf (ios::scientific);
    cout << sqrt (2) << endl;
    cout.setf (ios::fixed);
    cout << sqrt (2) << endl;
    cout << 12.00 << endl;
    cout << showpoint << 12.00 << endl;
    cout << noshowpoint << 12.00 << endl;
    ifstream ifs ("stream.txt");
    ifs.unsetf (ios::skipws);
    char c;
    while (ifs >> c)
        cout << c;
    ifs.setf (ios::skipws);
    ifs.clear (); // 复位
    ifs.seekg (ios::beg);
    while (ifs >> c)
        cout << c;
    ifs.close ();
    cout << endl;
    int i = 1234;
    double d = 56.78;
    string s = "tarena";
    ostringstream oss;
    oss << i << ' ' << d << ' ' << s;
    string str = oss.str ();
    cout << str << endl;
    str = "hello 3.14 pai";
    istringstream iss;
    iss.str (str);
    iss >> s >> d >> str;
    cout << s << ' ' << d << ' ' << str << endl;
    return 0;
}

write.cpp

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
class Dog {
public:
    Dog (const string& name = "", int age = 0) :
        m_age (age) {
        strcpy (m_name, name.c_str ());
    }
    void print (void) const {
        cout << m_name << "" << m_age << endl;
    }
private:
    char m_name[128];
    int m_age;
};
int main (void) {
    ofstream ofs ("dog.dat");
    Dog dog ("小白", 25);
    ofs.write ((char*)&dog, sizeof (dog));
    ofs.close ();
    ifstream ifs ("dog.dat");
    Dog dog2;
    ifs.read ((char*)&dog2, sizeof (dog2));
    dog2.print ();
    ifs.close ();
    return 0;
}

xor.cpp

#include <iostream>
#include <fstream>
#include <stdexcept>
#include <cstdlib>
using namespace std;
#define BUFSIZE (1024*10)
int _xor (const char* src, const char* dst,
    unsigned char key) {
    ifstream ifs (src, ios::binary);
    if (! ifs) {
        perror ("打开源文件失败");
        return -1;
    }
    ofstream ofs (dst, ios::binary);
    if (! ofs) {
        perror ("打开目标文件失败");
        return -1;
    }
    char* buf = NULL;
    try {
        buf = new char[BUFSIZE];
    }
    catch (bad_alloc& ex) {
        cout << ex.what () << endl;
        return -1;
    }
    while (ifs.read (buf, BUFSIZE)) {
        for (size_t i = 0; i < BUFSIZE; ++i)
            buf[i] ^= key;
        if (! ofs.write (buf, BUFSIZE)) {
            perror ("写入文件失败");
            return -1;
        }
    }
    if (! ifs.eof ()) {
        perror ("读取文件失败");
        return -1;
    }
    for (size_t i = 0; i < ifs.gcount (); ++i)
        buf[i] ^= key;
    if (! ofs.write (buf, ifs.gcount ())) {
        perror ("写入文件失败");
        return -1;
    }
    delete[] buf;
    ofs.close ();
    ifs.close ();
    return 0;
}
int enc (const char* plain, const char* cipher) {
    srand (time (NULL));
    unsigned char key = rand () % 256;
    if (_xor (plain, cipher, key) == -1)
        return -1;
    cout << "密钥:" << (unsigned int)key << endl;
    return 0;
}
int dec (const char* cipher, const char* plain,
    unsigned char key) {
    return _xor (cipher, plain, key);
}
int main (int argc, char* argv[]) {
    if (argc < 3) {
        cerr << "用法:" << argv[0]
            << " <明文文件> <密文文件>" << endl;
        cerr << "用法:" << argv[0]
            << " <密文文件> <明文文件> <密钥>"
            << endl;
        return -1;
    }
    if (argc < 4)
        return enc (argv[1], argv[2]);
    else
        return dec (argv[1], argv[2],
            atoi (argv[3]));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xuxaut-558/p/10018349.html