유 니 버 설 단 방향 링크 디자인 (2) - 인터페이스의 실현
7890 단어 데이터 구조유 니 버 설 단 방향 링크
/***************************slist.c**********************************/
#include "slist.h"
#include "typedef.h"
#define SLIST_HEAD 0
#define SLIST_TAIL -1
typedef struct _SListNode
{
void *data;
struct _SListNode *next;
}SListNode;
struct _SList
{
SListNode* first;
SlistDataDestroyFunc data_destroy;
void* data_destroy_ctx;
};
static SListNode* slit_create_node(void *data)
{
SListNode* node = (SListNode*)malloc(sizeof(SListNode));
if(NULL != node)
{
node->data = data;
node->next = NULL;
}
return node;
}
SList* slist_create(SlistDataDestroyFunc data_destroy, void* data_destroy_ctx)
{
SList* this = NULL;
this = (SList*)malloc(sizeof(SList));
if(NULL != this)
{
this->first = NULL;
this->data_destroy = data_destroy;
this->data_destroy_ctx = data_destroy_ctx;
}
return this;
}
Ret slist_prepend(SList* this, void* data)
{
return slist_insert(this, SLIST_HEAD, data);
}
Ret slist_append(SList* this, void* data)
{
return slist_insert(this, SLIST_TAIL, data);
}
static SListNode* slist_get_prev_node(SList* this, size_t index, int fail_return_last)
{
return_val_if_fail(this != NULL, NULL);
SListNode* node = this->first;
index--;
while(node!= NULL && node->next != NULL && index > 0)
{
node = node->next;
index--;
}
if(!fail_return_last)
{
return node = index > 0 ? NULL: node;
}
return node;
}
Ret slist_insert(SList* this, size_t index, void* data)
{
SListNode* node = NULL;
SListNode* cursor = NULL;
return_val_if_fail(this != NULL, RET_INVALIDPARM);
node = slit_create_node(data);
if(NULL == node)
{
return RET_OOM;
}
//null list
if(this->first == NULL)
{
this->first = node;
return RET_OK;
}
cursor = (index == 0) ? NULL: slist_get_prev_node(this, index, 1);
if(index >= 0 && index < slist_length(this))
{
//head node
if(NULL == cursor)
{
cursor = this->first;
this->first = node;
node->next = cursor;
}
else
{
node->next = cursor->next;
cursor->next = node;
}
}
else
{
/*default insert to tail if not find*/
cursor->next = node;
node->next = NULL;
}
return RET_OK;
}
Ret slist_delete(SList* this, size_t index)
{
return_val_if_fail(this != NULL, RET_INVALIDPARM);
SListNode* node = NULL;
SListNode* tmp = NULL;
if(-1 == index)
{
return RET_OK;
}
//locate prev node of current node, which is different from dlist
node = slist_get_prev_node(this, index, 1);
if(0 == index)
{
node = this->first;
this->first = node->next;
free(node);
node = NULL;
}
else
{
tmp = node->next;
node->next = node->next->next;
free(tmp);
tmp = NULL;
}
return RET_OK;
}
Ret slist_get_by_index(SList* this, size_t index, void** data)
{
return_val_if_fail(this != NULL, 0);
SListNode* prev_node = NULL;
if(index == 0)
{
*data = this->first->data;
return RET_OK;
}
prev_node = slist_get_prev_node(this, index, 1);
if(NULL != prev_node)
{
*data = prev_node->next->data;
}
return (prev_node != NULL) ? RET_OK : RET_FAILED;
}
Ret slist_set_by_index(SList* this, size_t index, void* data)
{
return_val_if_fail(this != NULL, 0);
SListNode* prev_node = NULL;
if(0 == index)
{
this->first->data = data;
return RET_OK;
}
prev_node = slist_get_prev_node(this, index, 1);
if(prev_node != NULL)
{
prev_node->next->data = data;
}
return (prev_node != NULL) ? RET_OK : RET_FAILED;
}
size_t slist_find(SList* this, SlistDataCmpFunc cmp, void* data)
{
return_val_if_fail(this != NULL, 0);
size_t index = 0;
SListNode* node = this->first;
while(node != NULL)
{
if(0 == cmp((void*)node->data, data))
{
return index;
}
node = node->next;
index++;
}
/*return -1 if not find */
return -1;
}
size_t slist_length(SList* this)
{
return_val_if_fail(this != NULL, 0);
size_t length = 0;
SListNode* node = this->first;
while(node != NULL)
{
node = node->next;
length++;
}
return length;
}
static void slist_destroy_data(SList* this, void* data)
{
if(this->data_destroy != NULL)
{
this->data_destroy(this->data_destroy_ctx, data);
}
return;
}
static void slist_destroy_node(SList* this, SListNode* node)
{
if(node != NULL)
{
node->next = NULL;
slist_destroy_data(this, node->data);
free(node);
}
}
void slist_destroy(SList* this)
{
return_if_fail(this != NULL);
SListNode* iter = this->first;
SListNode* next = NULL;
while(iter != NULL)
{
next = iter->next;
slist_destroy_node(this, iter);
iter = next;
}
this->first = NULL;
free(this);
return;
}
Ret slist_foreach(SList* this , SlistDataVisitFunc visit, void* data)
{
return_val_if_fail(this != NULL, RET_INVALIDPARM);
SListNode* node = this->first;
while(node != NULL)
{
visit(data, node->data);
node = node->next;
}
return RET_OK;
}
SList* slist_reverse(SList* this)
{
assert(NULL != this);
SListNode* pPrev = NULL;
SListNode* pCurrent = this->first;
SListNode* pNext = pCurrent->next;
while(pNext->next != NULL)
{
pCurrent->next = pPrev;
pPrev = pCurrent;
pCurrent = pNext;
pNext = pNext->next;
}
pCurrent->next = pPrev;
pPrev = pCurrent;
pNext->next = pCurrent;
this->first = pNext;
return this;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.