1. 程式人生 > >6.1-資料結構&演算法-堆疊與佇列

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;
}