链表的介绍:
链表可以说是一种最为基础的数据结构。在维护集合数据的时候拥有很大的帮助,尤其是在增,删上拥有很大的效率今天总结一下曾经学习的链表。
在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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。