您的位置:首页 > 其它

链表的增、删、查、找

2017-12-20 21:01 127 查看
基本结构

typedef int DataType;

typedef struct SListNode

{

struct SListNode* _next;

DataType _data;

}SListNode;

链表结构分为两部分,一部分是数据域,存放的是节点的数据部分,另一部分是指针域,保存下一节点的地址

新建节点

和动态顺序表不一样,每次只开辟一个节点的空间,将其节点的指针域赋为空

代码:

SListNode* BuySListNode(DataType x)
{
SListNode *NewNode =(SListNode *) malloc(sizeof(SListNode));
if (NewNode==NULL)
{
perror("申请失败");
exit(EXIT_FAILURE);

}
NewNode->_data = x;
NewNode->_next = NULL;

return NewNode;
}


打印链表

动态顺序表是通过下标来进行访问,而链表是通过指针访问到每一个节点,当某一节点的指针域为空时,说明链表到尾

代码:

void SListPrint(SListNode* pHead)
{

while (pHead != NULL)
{
printf("%d  ", pHead->_data);
pHead = pHead->_next;
}
printf("\n");
}


链表的头插(过程如下图)



代码:

void SListPushFront(SListNode** ppHead, DataType x)
{

if ((*ppHead) == NULL)
{
SListNode *cur = BuySListNode(x);
*ppHead = cur;
}
else
{
SListNode *cur = BuySListNode(x);
cur->_next = *ppHead;
*ppHead = cur;

}

}


链表头删(过程如下图)



代码:

void SListPopFront(SListNode** ppHead)
{
if (*ppHead == NULL)
{
printf("list is empty\n");
}

else
{
SListNode *cur = *ppHead;
free(cur);
*ppHead = (*ppHead)->_next;

}

}


尾插(过程与头插想类似在这里不在画图)

代码:

void SListPushBack(SListNode** ppHead, DataType x)
{
assert(ppHead);
SListNode *cur = *ppHead;
if (*ppHead == NULL)
{
*ppHead = BuySListNode(x);
}
else
{
while (cur->_next != NULL)
{
cur = cur->_next;
}

cur->_next = BuySListNode(x);

}

}


尾删

代码:

void SListPopBack(SListNode** ppHead)
{

SListNode *cur = *ppHead;
if (*ppHead == NULL)
{
printf("List is empty\n");
}
else if ((*ppHead)->_next == NULL)
{
free(*ppHead);
*ppHead = NULL;
}
else
{
while (cur->_next->_next != NULL)
{
cur = cur->_next;
}

free(cur->_next);
cur->_next = NULL;
}

}


任意位置插入(指头插)

在这里需要注意几点:

1)链表为空时,只需调用头插即可

2)链表有一个及以上节点时,需注意保存该位置的前一位置,将其与前一位置相连



代码:

void SListInsest(SListNode** ppHead, SListNode* pos, DataType x)
{
assert(*ppHead);

SListNode* prev = *ppHead;//记录pos位置的前一个节点
SListNode* cur = *ppHead;//头结点

if (pos == cur)
{
SListPushFront(ppHead, x);
}
else
{
while (prev->_next != pos)
{
prev = prev->_next;
}
SListNode* NewNode = BuySListNode(x);
NewNode->_next = prev->_next;
prev->_next = NewNode;
}
}


任意位置删除(删除方法类似头插,不在画图)

代码:

void SListErase(SListNode** ppHead, SListNode* pos)
{

if (*ppHead == NULL)
{
printf("list is empty\n");
}
else
{
if (pos == *ppHead)
{

SListNode *cur = *ppHead;
(*ppHead) = (*ppHead)->_next;
free(cur);
}
else if (pos == NULL)
{
SListPopBack(&pos);
}
else
{
SListNode* prev = *ppHead;
while (prev->_next != pos)
{
prev = prev->_next;
}

prev->_next = pos->_next;
free(pos);
}

}

}


下面给出完整代码及测试用例:

SeqList.c:

  SListNode* list;

//新建一个节点
SListNode* BuySListNode(DataType x) { SListNode *NewNode =(SListNode *) malloc(sizeof(SListNode)); if (NewNode==NULL) { perror("申请失败"); exit(EXIT_FAILURE); } NewNode->_data = x; NewNode->_next = NULL; return NewNode; }

//打印链表
void SListPrint(SListNode* pHead) { while (pHead != NULL) { printf("%d ", pHead->_data); pHead = pHead->_next; } printf("\n"); }

//释放节点
void SListDestory(SListNode** ppHead)
{
assert(ppHead);
free(*ppHead);
*ppHead = NULL;

}

//尾插
void SListPushBack(SListNode** ppHead, DataType x)
{
assert(ppHead);
SListNode *cur = *ppHead;
if (*ppHead == NULL)
{
*ppHead = BuySListNode(x);
(*ppHead)->_next = NULL;
}
else
{
while (cur->_next != NULL)
{
cur = cur->_next;
}

cur->_next = BuySListNode(x);

}

}

//尾删
void SListPopBack(SListNode** ppHead)
{

SListNode *cur = *ppHead;
if (*ppHead == NULL)
{
printf("List is empty\n");
}
else if ((*ppHead)->_next == NULL)
{
free(*ppHead);
*ppHead = NULL;
}
else
{
while (cur->_next->_next != NULL)
{
cur = cur->_next;
}
free(cur->_next);
cur->_next = NULL;
}

}

//头插
void SListPushFront(SListNode** ppHead, DataType x)
{

if ((*ppHead) == NULL)
{
SListNode *cur = BuySListNode(x);
*ppHead = cur;
}
else
{
SListNode *cur = BuySListNode(x);
cur->_next = *ppHead;
*ppHead = cur;

}

}

//头删
void SListPopFront(SListNode** ppHead)
{
if (*ppHead == NULL)
{
printf("list is empty\n");
}

else
{
SListNode *cur = *ppHead;
*ppHead = (*ppHead)->_next;
free(cur);

}

}

//任意位置插入
void SListInsest(SListNode** ppHead, SListNode* pos, DataType x)
{
assert(ppHead);
//assert(pos);
SListNode* prev = *ppHead;//记录pos位置的前一个节点
SListNode* cur = *ppHead;//头结点

if (pos == cur)
{
SListPushFront(ppHead, x);
}
else
{
while (prev->_next != pos)
{
prev = prev->_next;
}
SListNode* NewNode = BuySListNode(x);
NewNode->_next = prev->_next;
prev->_next = NewNode;
}
}

//查找
SListNode* SListFind(SListNode* pHead, DataType x)
{
assert(pHead);
SListNode *cur = pHead;
while (cur != NULL)
{
if (cur->_data == x)
{
return cur;
}
cur = cur->_next;
}
return NULL;

}

//任意位置删除
void SListErase(SListNode** ppHead, SListNode* pos) { if (*ppHead == NULL) { printf("list is empty\n"); } else { if (pos == *ppHead) { SListNode *cur = *ppHead; (*ppHead) = (*ppHead)->_next; free(cur); } else if (pos == NULL) { SListPopBack(&pos); } else { SListNode* prev = *ppHead; while (prev->_next != pos) { prev = prev->_next; } prev->_next = pos->_next; free(pos); } } }


test.c

//测试尾插
void TestSListPushBack()
{

list = NULL;
SListPushBack(&list, 0);
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPrint(list);

}

//测试尾删
void TestSListPopBack(SListNode** ppHead)
{
list = NULL;
SListPushBack(&list, 0);
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPrint(list);

SListPopBack(&list);
SListPopBack(&list);
SListPopBack(&list);
SListPopBack(&list);
SListPopBack(&list);
SListPopBack(&list);

SListPrint(list);

}

//测试头插
void TestSListPushFront()
{
list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPrint(list);

}

//测试头删
void TestSListPopFront()
{
list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPrint(list);

SListPopFront(&list);
SListPopFront(&list);
SListPopFront(&list);
SListPopFront(&list);
SListPopFront(&list);

SListPrint(list);

}

//测试查找
void  TestSListFind()
{

list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);

SListNode* cur = SListFind(list, 3);
printf("%d\n", cur->_data);

}

//测试任意位置插入
void TestSListInsest()
{

list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPrint(list);

SListNode *ret = SListFind(list, 0);
SListInsest(&list, ret, 78);
ret = SListFind(list, 4);
SListInsest(&list, ret, 78);
ret = SListFind(list, 2);
SListInsest(&list, ret, 78);

SListPrint(list);

}

//测试任意位置删除
void TestSListErase(SListNode** ppHead, SListNode* pos)
{
list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPrint(list);

SListNode *ret = SListFind(list, 4);
SListInsest(&list, ret, 23);
SListPrint(list);

ret = SListFind(list, 4);
SListErase(&list, ret);
ret = SListFind(list, 23);
SListErase(&list, ret);
ret = SListFind(list, 0);
SListErase(&list, ret);
SListPrint(list);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表 结构 数据