二哈开头,关于数据结构上面的单链表
文章目录
基本结构
这个结构通过结构体来实现这个过程。
结构体
struct ListNode{
int data;
ListNode *next;
}
通过next对于下一个节点储存信息。
对于链表的操作
创建一个新的结构体
SListNode *MakeSListNode(SLTDataType x){//创建一个结构体,赋值x
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
if (newnode == NULL) {
printf("创建失败");
exit(-1);
}
else{
newnode -> data = x;
newnode -> next = NULL;
}
return newnode;
}
通过对于结构体的直接创建实现内容的插入,实现内容的封装。
尾插
void SListPushBack(SListNode** pphead, SLTDataType x){
assert(pphead);
if (*pphead == NULL) {
*pphead = MakeSListNode(x);
}
else if ((*pphead) -> next == NULL){
*pphead = MakeSListNode(x);
}
else{
while ((*pphead) -> next != NULL) {
*pphead = (*pphead) -> next;
}
(*pphead)->next = MakeSListNode(x);
}
}
通过找尾巴来实现内容的插入!时间复杂度为O(n),其中n为链表的节点个数。
插入在某一个位置
void SlistInsertAfter(SListNode *pos,SLTDataType x){
assert(pos);
SListNode *cur = pos ->next;
pos->next = MakeSListNode(x);
pos -> next -> next = cur;
}
通过这个可以淘汰部分尾,以及头删除插代码。只用吧pos更换成为尾指针可以了!
某一个位置的删除
void SListErase(SListNode **pphead,SListNode *pos){
assert(pphead);
assert(pos);
if (*pphead == pos) {
SListPopFront(pphead);
}
else{
SListNode *prev = *pphead;
while (prev -> next != pos) {
prev = prev -> next;
}
prev -> next = pos ->next;
free(pos);
pos = NULL;
}
}
这个过程可以用于省去头删除和尾部删除。
对于整个链表删除
void SListDistroy(SListNode** pphead){
assert(pphead);
SListNode *cur = *pphead;
while (cur) {
SListNode *next = cur ->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
———————————————————————————————————————————————
双链表
具体的过程基本相同,只是增加了一个指针指向前一个位置信息!结构体增加了一个项目!
struct ListNode {
int data ;
struct *next;
struct *prev;//存放上一个节点的信息
}
而且其他的操作更加简单!