第二章目錄
0x0000 線性表的概念及抽象數據類型定義
0x0001 線性表的順序存儲
0x0010 線性表的鏈式存儲
1. 單鏈表
親自調試了一遍, 問題已經修改, 如果還有bug歡迎路過的大佬指正!
/***
* @Author : acmaker
* @Date : 2020-03-10 11:33:03
* @LastEditTime: 2020-03-16 14:14:51
* @FilePath : \myCPlusPlusCode\DataStructure\LinearList\SingalLinkedList.cpp
* @Website : http://csdn.acmaker.vip
* @Description :
*/
#include <bits/stdc++.h>
using namespace std;
#define rg register
#define sc scanf
#define pf printf
typedef long long ll;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
// 線性表的鏈式存儲結構
typedef char ElemType;
typedef struct Node {
ElemType data;
Node* next;
}Node, *LinkedList;
LinkedList L;
long long ListLength ( LinkedList L );
void InitList ( LinkedList *L );
void CreateFromHead ( LinkedList L );
void CreateFromTail ( LinkedList L );
Node* Get ( LinkedList L, long long pos );
Node* Locate ( LinkedList L, ElemType key );
int InsList ( LinkedList L, int pos, ElemType e );
int DelList ( LinkedList L, int pos, ElemType *e );
void DestroyList ( LinkedList L );
void reverseList ( LinkedList );
int main ( ) { // freopen( "F:\\in\\.txt" , "r" , stdin );
InitList( &L );
// CreateFromHead( L );
CreateFromTail( L );
cout << Get( L, 3 )->data << endl;
cout << Get( L, 2 )->data << endl;
cout << Locate( L, '3' ) << endl;
cout << InsList( L, 1, '8' ) << endl;
ElemType backup;
cout << DelList( L, 1, &backup ) << endl;
DestroyList( L );
return 0 ;
}
// 代碼實現.
/***
* @description: 計算帶頭結點的單鏈表 長度
* @param :
* @return:
*/
long long ListLength ( LinkedList L ) {
Node *p = L->next;
long long i;
for ( i = 0; p!=NULL; ++i ) {
p = p->next;
}
return i;
}
/***
* @description: 初始化頭結點, 注意傳遞的參數是頭指針!
* @param :
* @return:
*/
void InitList ( LinkedList *t ) {
*t = (LinkedList)malloc( sizeof(Node) );
(*t)->next = NULL;
}
/***
* @description: 頭插法建表
* @param :
* @return:
*/
void CreateFromHead ( LinkedList L ) {
Node *s;
bool state = true; // false爲輸入結束
ElemType input;
while ( state ) {
cin >> input;
if ( input=='$' ) state = false;
else {
s = (Node*)malloc( sizeof(Node) );
s->data = input;
s->next = L->next;
L->next = s;
}
}
}
/***
* @description: 尾插法建表
* @param :
* @return:
*/
void CreateFromTail ( LinkedList L ) {
Node *s, *r = L;
bool state = true;
ElemType input;
while ( state ) {
cin >> input;
if ( input=='$' ) state = false, r->next = NULL;
else {
s = (Node*)malloc( sizeof(Node) );
s->data = input;
r->next = s;
r = s;
}
}
}
/***
* @description: 帶頭結點單鏈表查找第 i 個結點
* @param :
* @return:
*/
Node* Get ( LinkedList L, long long pos ) {
Node* p = L;
long long i = 0;
for ( ; (p->next!=NULL)&&(i<pos); ++i ) {
p = p->next;
}
return (i==pos ? p : NULL);
}
/***
* @description: 帶頭結點的單鏈表 查找值爲key的結點
* @param :
* @return: 返回查找到的值的地址...貌似沒啥用...
*/
Node* Locate ( LinkedList L, ElemType key ) {
Node* p = L->next;
for ( ; p!=NULL; p=p->next ) {
if ( p->data==key ) break;
}
return p;
}
/***
* @description: 帶頭結點的單鏈表 插入
* @param :
* @return:
*/
int InsList ( LinkedList L, int pos, ElemType e ) {
if ( pos<=0 ) return ERROR;
Node *pre = L;
for ( long long i = 0; (pre!=NULL)&&(i<pos-1); ++i ) {
pre = pre->next;
}
if ( pre==NULL ) {
cout << "超出鏈表最大長度!" << endl;
return ERROR;
}
Node *s = (Node*)malloc( sizeof(Node) );
s->data = e;
s->next = pre->next;
pre->next = s;
return OK;
}
/***
* @description: 帶頭結點的單鏈表 刪除一個元素
* @param : 注意, ElemType參數需要傳遞引用!
* @return:
*/
int DelList ( LinkedList L, int pos, ElemType *e ) {
if ( pos<0 ) return ERROR;
Node *pre = L; // 注意刪除的時候從頭結點開始算
for ( long long i = 0; (pre->next!=NULL)&&(i<pos-1); ++i ) {
pre = pre->next;
}
if ( pre->next==NULL ) {
cout << "超出鏈表最大長度!" << endl;
return ERROR;
}
Node *t = pre->next;
pre->next = t->next;
*e = t->data;
free(t);
return OK;
}
/***
* @description: 銷燬單鏈表
* @param :
* @return:
*/
void DestroyList ( LinkedList L ) {
Node *p = L, *t;
while ( p->next!=NULL ) {
t = p->next;
free(p);
p = t;
}
}
/***
* @description: 逆置單鏈表( 使用頭插法 )
* @param :
* @return:
*/
void reverseList( LinkedList L ) {
Node *p = L->next;
L->next = NULL;
for ( ; p!=NULL; p=q ) {
q = p->next;
p->next = L->next;
L->next = p;
}
}
計算相關
在長度爲N的順序表仲,插入一個新元素平均需要移動表中_______個元素?刪除一個元素平均需要移動_______個
在長度爲N的順序表仲,插入一個新元素平均需要移動表中________個元素,刪除一個元素平均需要移動_______個元素,
- | 在表頭操作需要移動幾個 | 在表尾操作需要移動幾個 | 一共需要移動幾個 | 平均需要移動幾個 |
---|---|---|---|---|
插入 | n | 0 | n/2 | n/2 / (n+1) |
刪除 | n-1 | 0 | (n-1)/2 | (n-1)/2 / n |
2. 循環鏈表
循環鏈表的建表, 增刪改查 無非就是把最後尾指針指向表頭罷了, 不重複了
以下是合併兩個單鏈表爲 循環鏈表 的代碼, 待測試…
/***
* @Author : acmaker
* @Date : 2020-03-16 09:42:12
* @LastEditTime: 2020-03-16 10:22:15
* @FilePath : \myCPlusPlusCode\DataStructure\LinearList\CircleLinkedList.cpp
* @Website : http://csdn.acmaker.vip
* @Description :
*/
#include <bits/stdc++.h>
#include "SingalLinkedList.cpp"
using namespace std;
#define rg register
#define sc scanf
#define pf printf
typedef long long ll;
typedef char ElemType;
typedef struct CNode {
ElemType data;
CNode* next;
}CNode, *CircleLinkedList;
/***
* @description: 傳入兩個單鏈表的表頭, 合併爲 循環鏈表
* @param :
* @return:
*/
CircleLinkedList merge_1 ( CircleLinkedList LA, CircleLinkedList LB ) {
CNode *pa, *pb;
while ( pa->next!=NULL ) pa->next;
while ( pb->next!=NULL ) pb->next;
pa->next = LB->next;
free( LB );
pb->next = LA;
return LA;
}
/***
* @description: 傳入兩個單鏈表的表尾, 合併爲 循環鏈表
* @param :
* @return:
*/
CircleLinkedList merge_2 ( CircleLinkedList RA, CircleLinkedList RB ) {
CNode *t = RA;
RA->next = RB->next->next;
free( RB->next );
RB->next = t->next;
return RB; // 返回新的表尾
}
int main ( ) { // freopen( "F:\\in\\.txt" , "r" , stdin );
return 0 ;
}
3. 雙向鏈表
插入操作
刪除操作
雙向鏈表就是多了了前驅指針, 增刪改查的時候能靈活些, 注意掛鏈都是先操作前驅的
代碼待驗證…
/***
* @Author : acmaker
* @Date : 2020-03-16 10:11:31
* @LastEditTime: 2020-03-16 11:26:05
* @FilePath : \myCPlusPlusCode\DataStructure\LinearList\DoubleLinkedList.cpp
* @Website : http://csdn.acmaker.vip
* @Description :
*/
#include <bits/stdc++.h>
#include "SingalLinkedList.cpp"
using namespace std;
#define rg register
#define sc scanf
#define pf printf
typedef long long ll;
#define OK 1
#define Error 0
typedef char ElmeType;
typedef struct {
ElmeType data;
DNode *prior, *next;
}DNode, *DoubleLinkedList;
int InsPrior ( DoubleLinkedList L, int pos, ElemType e ) {
if ( pos<0 ) return ERROR;
DNode *p = L->next;
for ( long long i = 0; (p!=NULL)&&(i<pos); ++i ) {
p = p->next;
}
if ( p==NULL ) {
cout << "超出鏈表最大長度!" << endl;
return ERROR;
}
DNode *s = (DNode*)malloc( sizeof(DNode) );
s->data = e;
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s->next;
return OK;
}
int Del ( DoubleLinkedList L, int pos, ElemType *e ) {
if ( pos<0 ) return ERROR;
DNode *p = L;
for ( long long i = 0; (p!=NULL)&&(i<pos); ++i ) {
p = p->next;
}
if ( p==NULL ) {
cout << "超出鏈表最大長度!" << endl;
return ERROR;
}
*e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free( p );
return OK;
}
int main ( ) { // freopen( "F:\\in\\.txt" , "r" , stdin );
return 0 ;
}
** 靜態鏈表
待填坑…
0x0011 線性表應用
1.> 單鏈表的置換
其實就是頭插法建表的思想, 重複執行着 當前節點 指向 上一個節點, 直到表尾.
/***
* @description: 逆置單鏈表( 使用頭插法 )
* @param :
* @return:
*/
void reverseList( LinkedList L ) {
Node *p = L->next, *q;
L->next = NULL;
for ( ; p!=NULL; p=q ) {
q = p->next;
p->next = L->next;
L->next = p;
}
}