標籤:演算法 鏈表 ios objetive-c 資料結構
鏈表的介紹:
鏈表可以說是一種最為基礎的資料結構。在維護集合資料的時候擁有很大的協助,尤其是在增,刪上擁有很大的效率今天總結一下曾經學習的鏈表。
在ios的開發中,掌握一些常用的演算法可以協助我們更加有效率的開發。
鏈表的總類:
今天先來講述下單鏈表:元素之間由一個單獨的指標連結。這種結構的鏈表允許從第一個元素開始遍曆到最後一個元素。
各元素之間通過一個指標串連起來而組成。每個元素包含兩個部分:資料成員和一個被稱為next的指標。通過這好種結構,將每個元素的next指標設定為指向其後面的元素。最後一個元素的Next設定為NULL,簡單的表示鏈表的尾端。鏈表開始處的元素是”head“,鏈表的末尾的元素稱為”tail“。
圖一
根據上面說的,其實我們可以把鏈表看作一系列連續的元素,要知道這些元素是動態分配在記憶體中的。其實元素與元素之間的串連是為了保證我們能夠訪問到每個元素。如果其中有一個連結被丟失,那麼從這個連結開始往後的所有連結都將被丟失。
我曾經在一本書上看過一句話:“你的弱點又多弱,你的強度就有多強”,這句話來形容鏈表非常的恰當。
進入今天的主題:
單鏈表介面的定義:初始化鏈表:
-(void)listInit :(List*) list;
該函數必須在其他動作之前調用。,使用listInit初始化一個鏈表,方便我們執行其他動作。初始化非常簡單,只需要將size設定為0,head與tail設定為null,就完成了初始化操作。
在指定的element後添加:
-(int)listInsNext:(List*) list over:(ListElemt *) element over:(ListElemt *)newElement;
簡單的說,插入操作就是對鏈表進行新的串連,例如有兩個節點A和C,要在A節點後加入B節點。首先先讓B的next指標指向C。然後C,然後A的next指標指向B。這樣就完成了簡單的操作。但是但是當插入到head位置的話,新元素前面就沒有節點了,這樣怎麼辦?很簡單,只需要將新元素next指標指向當前鏈表的頭部就可以了。當傳入的element為空白,直接插入到頭部就可以了。
圖一:
移除指定element後的元素:
-(int)listRemNext:(List*) list over:(ListElemt *) element;
移除element身後的元素,而不是element本身,至於為什麼,我們後在以後進行說明。需要考慮兩點,移除前端節點,以及其他節點。
操作其實很簡單。例如有A,B,C三個節點,我們只需要申請一個D,讓D指向A的下一個元素,然後A的next指向A的next的next。這樣串連中我們就將B直接去掉,剩下A,C。之後ARC會幫我們自動回收掉B
圖二:
輸出鏈表
-(void)outPut:(List*) list;
採用一個迴圈,初始化一個指標pre,讓這個指標指向list的head。每次迴圈後進行判斷,並且重新規劃:pre = pre->next
以下為一些宏定義,方便我們快速存取和監測List和ListElemt:
#define list_size(list)((list)->size)#define list_head(list)((list)->head)#define list_tail(list)((list)->tail)#define list_is_head(list,element)((element)==(list)->head ? 1:0)#define list_is_tail(element)((element)->next = NULL ? 1:0)#define list_data(element)((element)->data)#define list_next(element)((element)->data)
ListElemt.h代碼:
//// ListElemt.h// ok//// Created by MrLoong on 15/8/8.// Copyright (c) 2015年 MrLoong. All rights reserved.//#import <Foundation/Foundation.h>@interface ListElemt : NSObject{ @public id data; @public ListElemt *next;}@end
list.h代碼如下:
// List.h// Created by MrLoong on 15/8/8.// Copyright (c) 2015年 MrLoong. All rights reserved.//#import <Foundation/Foundation.h>#import "ListElemt.h"@interface List : NSObject{ @public ListElemt *head; @public ListElemt *tail; @public int size;}//初始化鏈表-(void)listInit :(List*) list;//在指定的element後添加newElement-(int)listInsNext:(List*) list over:(ListElemt *) element over:(ListElemt *)newElement;//移除指定element後的元素-(int)listRemNext:(List*) list over:(ListElemt *) element;//輸出鏈表-(void)outPut:(List*) list;#define list_size(list)((list)->size)#define list_head(list)((list)->head)#define list_tail(list)((list)->tail)#define list_is_head(list,element)((element)==(list)->head ? 1:0)#define list_is_tail(element)((element)->next = NULL ? 1:0)#define list_data(element)((element)->data)#define list_next(element)((element)->data)@end
list.m代碼如下
//// List.m// ok//// Created by MrLoong on 15/8/8.// Copyright (c) 2015年 MrLoong. All rights reserved.//#import "List.h"@implementation List//初始化鏈表-(void) listInit:(List *)list{ list->size = 0; list->head = NULL; list->tail = NULL; return;}//在元素element後插入newElement -(int)listInsNext:(List *)list over:(ListElemt *)element over:(ListElemt *)newElement{ if(newElement==NULL){ return -1; } if(element==NULL){ if(list_size(list)==0){ list->tail = newElement; } newElement->next = list->head; list->head = newElement; } else{ if(element==NULL){ list->tail = newElement; } newElement->next = element->next; element->next = newElement; } list->size++; return 0;}//移除指定element後的元素-(int)listRemNext:(List *)list over:(ListElemt *)element{ ListElemt *oldEmement; if(list_size(list)==0){ return -1; } if (element==NULL) { oldEmement = list->head; list->head = list->head->next; if(list_size(list)==0){ list->tail = NULL; } } else{ if(element->next==NULL){ return -1; } oldEmement = element->next; element->next = element->next->next; if(element->next == NULL){ list->tail = element; } } // free((__bridge void *)(oldEmement)); return 0;}//輸出鏈表-(void)outPut:(List *)list{ ListElemt *pre = list->head; while (pre!=nil) { NSLog(@"%@",pre->data); pre = pre->next; }}@end
main.m代碼:
//// main.m// ok//// Created by MrLoong on 15/8/8.// Copyright (c) 2015年 MrLoong. All rights reserved.//#import <Foundation/Foundation.h>#import "List.h"#import "ListElemt.h"int main(int argc, const char * argv[]) { @autoreleasepool { //建立元素 List *list = [[List alloc] init]; [list listInit:list]; ListElemt *element1 = [[ListElemt alloc]init]; element1->data = [NSNumber numberWithInt:1]; ListElemt *element2 = [[ListElemt alloc]init]; element2->data = [NSNumber numberWithInt:2]; ListElemt *element3 = [[ListElemt alloc]init]; element3->data = [NSNumber numberWithInt:3]; ListElemt *element4 = [[ListElemt alloc]init]; element4->data = [NSNumber numberWithInt:4]; ListElemt *element5 = [[ListElemt alloc]init]; element5->data = [NSNumber numberWithInt:5]; ListElemt *element6 = [[ListElemt alloc]init]; element6->data = [NSNumber numberWithInt:6]; //建立元素 [list listInsNext:list over:list->head over:element1]; [list listInsNext:list over:element1 over:element2]; [list listInsNext:list over:element2 over:element3]; [list listInsNext:list over:element3 over:element4]; [list listInsNext:list over:element4 over:element5]; [list listInsNext:list over:element5 over:element6]; [list outPut:list]; //刪除element2後的元素element3 [list listRemNext:list over:element2]; printf("===========================================\n"); printf("插入完成\n"); printf("===========================================\n"); [list outPut:list]; printf("===========================================\n"); printf("刪除完成\n"); printf("===========================================\n"); } return 0;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
objective-c演算法詳解(一、鏈表)