單向鏈表 線性表的一種(能夠理解爲線性表的鏈式鏈式表示和實現)
指針
邏輯位置相鄰 物理位置不相鄰code
與線性表相比劣勢:不能隨機存取element
與線性表相比優點:插入和刪除較快it
鏈式存貯結構通常由一個個節點組成,每一個節點包含數據域和指針域,數據域裏存貯這個節點的數據,指針域裏存貯下個節點的地址。io
如下是C語言代碼實現(我的實驗代碼):
class
#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -2 typedef int ElemType; typedef int Status; /* * 存儲結構 */ typedef struct LNode { ElemType data; struct LNode *next; }LNode, *LinkList; /* * 初始化線性表 */ void InitList(LinkList *L) { *L = (LinkList) malloc(sizeof(LNode)); if (!L) { exit(OVERFLOW); } (*L)->next = NULL; } /* * 銷燬線性表 */ void DestroyList(LinkList *L) { LinkList temp; while (*L) { temp = (*L)->next; free(*L); *L = temp; } } /* * 清空線性表 */ void ClearList(LinkList L) { LinkList p = L->next; L->next = NULL; DestroyList(&p); } /* * 判斷是否爲空 */ Status isEmpty(LinkList L) { if (L->next) { return FALSE; } else { return TRUE; } } /* * 獲取長度 */ int GetLength(LinkList L){ int i = 0; LinkList p = L->next; while (p) { i++; p = p->next; } return i; } /* * 根據位置獲取元素 */ Status GetElem(LinkList L, int i, ElemType *e){ int j = 1; LinkList p = L->next; while (p && j < i) { j++; p = p->next; } if (!p || j > i) { return ERROR; } *e = p->data; return OK; } /* * 比較兩個元素是否相等 */ Status compare(ElemType e1, ElemType e2){ if (e1 == e2) { return 0; } else if (e1 < e2) { return -1; } else { return 1; } } /* * 查找指定元素的位置 */ int FindElem(LinkList L, ElemType e, Status (*compare)(ElemType, ElemType)){ int i = 0; LinkList p = L->next; while (p) { i++; if (!compare(p->data, e)) { return i; } p = p->next; } return 0; } /* * 獲取前驅元素 */ Status PreElem(LinkList L, ElemType cur_e, ElemType *pre_e){ LinkList q, p = L->next; while (p->next) { q = p->next; if (q->data == cur_e) { *pre_e = p->data; return OK; } p = q; } return ERROR; } /* * 獲取後繼元素 */ Status NextElem(LinkList L, ElemType cur_e, ElemType *next_e){ LinkList p = L->next; while (p->next) { if (p->data == cur_e) { *next_e = p->next->data; return OK; } p = p->next; } return ERROR; } /* * 插入元素 */ Status InsertElem(LinkList L, int i, ElemType e){ int j = 0; LinkList s, p = L; while (p && j < i - 1) { j++; p = p->next; } if (!p || j > i - 1) { return ERROR; } s = (LinkList) malloc(sizeof(LNode)); s->data = e; s->next = p->next; p->next = s; return OK; } /* * 刪除元素並返回值 */ Status DeleteElem(LinkList L, int i, ElemType *e){ int j = 0; LinkList q, p = L; while (p->next && j < i - 1) { j++; p = p->next; } if (!p->next || j > i - 1) { return ERROR; } q = p->next; p->next = q->next; *e = q->data; free(q); return OK; } /* * 訪問元素 */ void visit(ElemType e){ printf("%d ", e); } /* * 遍歷線性表 */ void TraverseList(LinkList L, void (*visit)(ElemType)){ LinkList p = L->next; while (p) { visit(p->data); p = p->next; } } int main(){ LinkList L; InitList(&L); ElemType e; int i; if (L) { printf("init success\n"); } if (isEmpty(L)) { printf("list is empty\n"); } for (i = 0; i < 10; i++) { InsertElem(L, i + 1, i); } if (GetElem(L, 1, &e)) { printf("The first element is %d\n", e); } printf("length is %d\n", GetLength(L)); printf("The 5 at %d\n", FindElem(L, 5, *compare)); PreElem(L, 6, &e); printf("The 6's previous element is %d\n", e); NextElem(L, 6, &e); printf("The 6's next element is %d\n", e); DeleteElem(L, 1, &e); printf("delete first element is %d\n", e); printf("list:"); TraverseList(L,visit); DestroyList(&L); if (!L) { printf("\ndestroy success\n"); } }
上面的理解難點在插入操做 插入節點的地方
List
順序存儲結構實現單項式的求和 (已經實現了稍後給連接)
遍歷
反轉鏈表
im