學習編程也有一段時間了,可是老是感受,本身缺乏一些什麼東西。編程一味的學習照着別人寫的習慣,沒有本身的思想,是不能有質的提高的。老是感受本身不能作什麼,對待代碼仍是缺乏基本的實現的能力,更不用說什麼技巧算法了。還須要的大量的聯繫。算法
我打算好好把數據結構的算法,實現如下,老是感受本身,看起來會了,可是實際動手機就寫不出來了。編程
本身只有不斷的總結,把該記住的東西理解了,才能駕輕就熟。。。。數據結構
公共的頭文件:#include "common.h"函數
#include<string.h> #include<ctype.h> #include<malloc.h> /* malloc()等 */ #include<limits.h> /* INT_MAX等 */ #include<stdio.h> /* EOF(=^Z或F6),NULL */ #include<stdlib.h> /* atoi() */ #include<io.h> /* eof() */ #include<math.h> /* floor(),ceil(),abs() */ #include<process.h> /* exit() */ /* 函數結果狀態代碼 */ #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 //infeasible /* #define OVERFLOW -2 由於在math.h中已定義OVERFLOW的值爲3,故去掉此行 */ typedef int Status; /* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */ typedef int Boolean; /* Boolean是布爾類型,其值是TRUE或FALSE */
#include "SingleList.h"學習
#pragma once #include "common.h" typedef int ElemType; //線性表的單鏈表存儲結構 struct LNode { ElemType data; LNode* next; }; typedef struct LNode* LinkList; class SingleList { public: SingleList(); ~SingleList(); public: //基本操做12個 Status InitList(LinkList*); Status DestroyList(LinkList*); Status ClearList(LinkList); Status ListEmpty(LinkList); Status ListLength(LinkList); Status GetElem(LinkList, int i, ElemType* e); Status LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType)); Status PriorElem(LinkList L, ElemType cur_e, ElemType* pre_e); Status NextElem(LinkList L, ElemType cur_e,ElemType* next_e); Status ListInsert(LinkList L,int i,ElemType e); Status ListDelete(LinkList L,int i,ElemType* e); Status ListTraverse(LinkList L,void(*vi)(ElemType)); };
"SingleList.cpp"測試
#include "SingleList.h" SingleList::SingleList() { } SingleList::~SingleList() { } Status SingleList::InitList(LinkList* L) { /*操做結果:構造一個空的線性表L*/ *L = (LinkList)malloc(sizeof(LNode)); //產生頭結點,並使L指向次頭結點 if (!*L) { exit(OVERFLOW); } (*L)->next = nullptr;//指針域空 return OK; } Status SingleList::DestroyList(LinkList*L) { /*初始條件:線性表L已經存在。操做結果:銷燬線性表*/ LinkList q; while (*L) { q = (*L)->next; free(*L); *L = q; } return OK; } Status SingleList::ClearList(LinkList L) /*不改變L*/ { /*初始條件:線性表L已經存在。操做結果:將L置爲空表*/ LinkList p, q; p = L->next;/*p指向第一個結點*/ while (p) { q = p->next; //先記錄下一結點,而後釋放當前結點 free(p); p = q; } L->next = nullptr; /*頭結點指針域爲空*/ return OK; } Status SingleList::ListEmpty(LinkList L) { if (L->next==nullptr) { return OK; } else { return ERROR; } } Status SingleList::ListLength(LinkList L) { int length=0; LinkList q=L->next; while (q) { length++; q = q->next; } return length; } Status SingleList::GetElem(LinkList L, int i, ElemType* e) { /* L爲帶頭結點的單鏈表的頭指針。當第i個元素存在時,其值賦給e並返回OK,不然返回ERROR */ LinkList q; q = L->next; int j = 1; /* j爲計數器 */ while (q&&j<i) /* 順指針向後查找,直到p指向第i個元素或p爲空 */ { j++; q = q->next; } if (!q || j>i) /*第i個元素不存在*/ { return ERROR; } *e = q->data; /*取第i個元素*/ return OK; } int SingleList::LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType)) { /* 初始條件: 線性表L已存在,compare()是數據元素斷定函數(知足爲1,不然爲0) */ /* 操做結果: 返回L中第1個與e知足關係compare()的數據元素的位序。 */ /* 若這樣的數據元素不存在,則返回值爲0 */ int i = 0; LinkList p = L->next; while (p) { i++; if (compare(p->data, e)) /* 找到這樣的數據元素 */ return i; p = p->next; } return 0; } Status SingleList::PriorElem(LinkList L, ElemType cur_e, ElemType *pre_e) { /* 初始條件: 線性表L已存在 */ /* 操做結果: 若cur_e是L的數據元素,且不是第一個,則用pre_e返回它的前驅, */ /* 返回OK;不然操做失敗,pre_e無定義,返回INFEASIBLE */ LinkList q, p = L->next; /* p指向第一個結點 */ while (p->next) /* p所指結點有後繼 */ { q = p->next; /* q爲p的後繼 */ if (q->data == cur_e) { *pre_e = p->data; return OK; } p = q; /* p向後移 */ } return INFEASIBLE; } Status SingleList::NextElem(LinkList L, ElemType cur_e, ElemType *next_e) { /* 初始條件:線性表L已存在 */ /* 操做結果:若cur_e是L的數據元素,且不是最後一個,則用next_e返回它的後繼, */ /* 返回OK;不然操做失敗,next_e無定義,返回INFEASIBLE */ LinkList p = L->next; /* p指向第一個結點 */ while (p->next) /* p所指結點有後繼 */ { if (p->data == cur_e) { *next_e = p->next->data; return OK; } p = p->next; } return INFEASIBLE; } Status SingleList::ListInsert(LinkList L, int i, ElemType e) /* 算法2.9。不改變L */ { /* 在帶頭結點的單鏈線性表L中第i個位置以前插入元素e */ int j = 0; LinkList p = L, s; while (p&&j<i - 1) /* 尋找第i-1個結點 */ { p = p->next; j++; } if (!p || j>i - 1) /* i小於1或者大於表長 */ return ERROR; s = (LinkList)malloc(sizeof(struct LNode)); /* 生成新結點 */ s->data = e; /* 插入L中 */ s->next = p->next; p->next = s; return OK; } Status SingleList::ListDelete(LinkList L, int i, ElemType *e) /* 算法2.10。不改變L */ { /* 在帶頭結點的單鏈線性表L中,刪除第i個元素,並由e返回其值 */ int j = 0; LinkList p = L, q; while (p->next&&j<i - 1) /* 尋找第i個結點,並令p指向其前趨 */ { p = p->next; j++; } if (!p->next || j>i - 1) /* 刪除位置不合理 */ return ERROR; q = p->next; /* 刪除並釋放結點 */ p->next = q->next; *e = q->data; free(q); return OK; } Status SingleList::ListTraverse(LinkList L, void(*vi)(ElemType)) /* vi的形參類型爲ElemType,與bo2-1.c中相應函數的形參類型ElemType&不一樣 */ { /* 初始條件:線性表L已存在 */ /* 操做結果:依次對L的每一個數據元素調用函數vi()。一旦vi()失敗,則操做失敗 */ LinkList p = L->next; while (p) { vi(p->data); p = p->next; } printf("\n"); return OK; }
測試main()spa
#include "common.h" #include "SingleList.h" Status comp(ElemType c1, ElemType c2) { //數據元素斷定函數(相等爲True,不然爲FALSE) if (c1 == c2) { return TRUE; } else return FALSE; } void visit(ElemType c) { printf("%d", c); } int main() { LinkList L; ElemType e, e0; Status i; int k; SingleList s; i = s.InitList(&L); for (int j = 1; j <= 5;j++) { i = s.ListInsert(L, 1, j); } printf("在L的表頭依次插入1~5後:L="); s.ListTraverse(L, visit); i = s.ListEmpty(L); printf("L是否空:i=%d(1:是 0:否)\n", i); for (int j = 1; j <= 10;j++) { s.ListInsert(L,j+5,j); } printf("在L的表尾依次插入1~10後:L="); s.ListTraverse(L,visit); s.GetElem(L,5,&e); printf("第5個元素的值爲:%d\n", e); for (int j = 0; j <= 1; j++) { k = s.LocateElem(L, j, comp); if (k) printf("第%d個元素的值爲%d\n", k, j); else printf("沒有值爲%d的元素\n", j); } for (int j = 1; j <= 2; j++) /* 測試頭兩個數據 */ { s.GetElem(L, j, &e0); /* 把第j個數據賦給e0 */ i = s.PriorElem(L, e0, &e); /* 求e0的前驅 */ if (i == INFEASIBLE) printf("元素%d無前驅\n", e0); else printf("元素%d的前驅爲:%d\n", e0, e); } for (int j = s.ListLength(L) - 1; j <= s.ListLength(L); j++)/*最後兩個數據 */ { s.GetElem(L, j, &e0); /* 把第j個數據賦給e0 */ i = s.NextElem(L, e0, &e); /* 求e0的後繼 */ if (i == INFEASIBLE) printf("元素%d無後繼\n", e0); else printf("元素%d的後繼爲:%d\n", e0, e); } k = s.ListLength(L); /* k爲表長 */ for (int j = k + 1; j >= k; j--) { i = s.ListDelete(L, j, &e); /* 刪除第j個數據 */ if (i == ERROR) printf("刪除第%d個數據失敗\n", j); else printf("刪除的元素爲:%d\n", e); } printf("依次輸出L的元素:"); s.ListTraverse(L, visit); s.DestroyList(&L); printf("銷燬L後:L=%u\n", L); return 0; }