1.链表
1.1 链表的概念及结构
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表 中的指针链接次序实现的 。
注意:
1.从上图可看出,链式结构在逻辑上是连续的。但是在物理上不一定连续
2.现实中的结点一般都是从堆上申请出来的
3.从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续
2 链表的实现
SList.h(头文件引用)
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <malloc.h>
#include <assert.h>typedef int SLTDataType;typedef struct SListNode
{SLTDataType data;struct SListNode* next;
}SLTNode;void SLTPrint(SLTNode* phead);SLTNode* BuySListNode(SLTDataType x);
void SLTPushBack(SLTNode ** pphead,SLTDataType x);
void SLTPushFront(SLTNode** pphead, SLTDataType x);
void SLTPopBack(SLTNode** pphead);
void SLTPopFront(SLTNode** pphead);//作业
SLTNode* SLTFind(SLTNode* pphead,SLTDataType x);//在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//在之后插入x
void SLTInsertAfter( SLTNode* pos, SLTDataType x);
//删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos);
//删除pos后一个位置
void SLTEraseAfter(SLTNode* phead,SLTNode* pos);
SList.c(函数功能的实现)
#include "SList.h"void SLTPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur != NULL){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");
}SLTNode* BuySListNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;return newnode;
}void SLTPushBack(SLTNode** pphead,SLTDataType x) //尾插//需要用二级指针,结构体指针(地址),传递实参
{assert(pphead); //空地址不正确//assert(*pphead);//空链表可以尾插SLTNode* newnode = BuySListNode(x);if (*pphead == NULL) //如果为空,则指向新创建元素{*pphead = newnode;}else //不为空则遍历到尾部插入数据{//需要用指针结构体指针,改变结构体,传递形参SLTNode* tail = *pphead;while (tail->next != 0){tail = tail->next;}tail->next = newnode;}
}void SLTPushFront(SLTNode** pphead, SLTDataType x)//头插
{assert(pphead); //空地址不正确assert(*pphead);//空链表不可以前删SLTNode* newnode = BuySListNode(x);newnode->next = *pphead;*pphead = newnode;
}void SLTPopBack(SLTNode** pphead) //尾删
{// 1.空assert(*pphead != NULL);// 2.一个节点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}// 3.多个节点else{SLTNode* tail = *pphead;while (tail->next->next){tail = tail->next;} free(tail->next);tail->next = NULL;}
}void SLTPopFront(SLTNode** pphead) //头删
{assert(pphead);assert(*pphead);SLTNode* newhead = (*pphead)->next;free(*pphead);*pphead = newhead;
}SLTNode* SLTFind(SLTNode*phead, SLTDataType x)
{assert(phead);SLTNode* tail = phead;while (tail){if (tail->data == x){return tail;}tail = tail->next;}return NULL;while (tail->data != x){tail = tail->next;if (tail->next==NULL&&tail->data!=x)
//下一个元素的值指向NULL并且数据值不等于要查找的数,既已遍历查找完毕并且没有找到数据{printf(" 输入错误,找不到输入值\n");return 0;}}printf("已找到:%d\n", x);return tail;
}void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{//有错误版本 ,地址近似一样(bug)find函数调试就好了assert(pos); assert(*pphead);if (pos == *pphead){SLTPushFront(pphead, x); }else{SLTNode* tail = *pphead;//在pos之前插入xwhile (tail->next != pos){tail = tail->next;}SLTNode* newnode = BuySListNode(x);tail->next = newnode;newnode->next = pos;}} void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);assert(pos->next);SLTNode* newnode = BuySListNode(x);//注意顺序,不然会照成死循环(画图)newnode->next = pos->next;pos->next = newnode;}void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pos);if (pos == *pphead){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);}}void SLTEraseAfter(SLTNode* phead,SLTNode* pos)
{//assert(pos);//检查是否为尾节点//assert(pos->next);SLTNode* posNext; //纪录要删除的节点//避免丢失无法FreeposNext = pos->next;//pos->next = pos->next->next;pos->next = posNext->next;free(posNext);posNext = NULL;
}
Test_1_16(各种功能的调试、函数、以及面试OJ题的接口实现)
#include "SList.h"void TestSList1()
{int n;printf("请输入链表长度:");scanf("%d", &n);printf("\n请依次输入每个节点的值:");SLTNode* plist = NULL; //第一个元素的地址 for (size_t i = 0; i < n; i++){int val;scanf("%d", &val);SLTNode* newnode = BuySListNode(val);//头插newnode->next = plist;plist = newnode;}SLTPrint(plist);SLTPushBack(&plist, 5);SLTPrint(plist);
}void TestSList()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 5);SLTPrint(plist);SLTPushFront(&plist, 10);SLTPushFront(&plist, 20);SLTPushFront(&plist, 30);SLTPushFront(&plist, 40);SLTPrint(plist);}void TestSList3()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 5);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);}void TestSList4()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 5);SLTPrint(plist);//SLTPopFront(&plist);//SLTPopFront(&plist);//SLTPrint(plist);SLTFind(plist, 1);SLTFind(plist, 2);SLTFind(plist, 3);SLTFind(plist, 4);SLTFind(plist, 5);SLTFind(plist, 0);
}void TestSlist5()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 5);SLTPrint(plist);SLTNode* pos = SLTFind(plist,4);if (pos)pos->data = 20;//在pos之前插入x//SLTInsert(&plist, pos, 5);SLTPrint(plist);}void TestSlist6()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 5);SLTPrint(plist);SLTNode* pos = SLTFind(plist, 4);SLTInsert(&plist, pos, 90);SLTPrint(plist);
}void TestSlist7()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 5);SLTPrint(plist);SLTNode* pos = SLTFind(plist, 4);SLTInsertAfter(pos, 90);SLTPrint(plist);
}void TestSlist8()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 5);SLTPrint(plist);SLTNode* pos = SLTFind(plist, 4);SLTErase(&plist,pos);SLTPrint(plist);
}void TestSlist9()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 5);SLTPrint(plist);SLTNode* pos = SLTFind(plist, 4);SLTEraseAfter(&plist, pos);SLTPrint(plist);
}struct SListNode* removeElement()
{;
}struct ListNode {int val;struct ListNode* next;};//
//struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
//{
// struct ListNode* first = pListHead;
// struct ListNode* tail = pListHead;
//
// while (first->next)
// {
// while (k>0&&first->next)
// {
// k--;
// first = first->next;
// }
// if (first->next==NULL)
// {
// return tail;
// }
// tail = tail->next;
// first = first->next;
// }
// //tail=tail->next;
// return tail->next;
//}struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
{if (pListHead == NULL){return pListHead;}struct ListNode* first = pListHead;struct ListNode* tail = pListHead;while (first->next){while (k > 0 && first->next){k--;first = first->next;//if (first->next == NULL && k > 0)//{// return NULL;//}}if (first->next == NULL&&k==1){return tail;}else{return NULL;}tail = tail->next;first = first->next;}//tail=tail->next;return tail->next;
}int main()
{struct SListNode* n1 = (struct ListNode*)malloc(sizeof(struct SListNode));struct SListNode* n2 = (struct ListNode*)malloc(sizeof(struct SListNode));struct SListNode* n3 = (struct ListNode*)malloc(sizeof(struct SListNode));struct SListNode* n4 = (struct ListNode*)malloc(sizeof(struct SListNode));struct SListNode* n5 = (struct ListNode*)malloc(sizeof(struct SListNode));n1->data = 1;n2->data = 2;n3->data = 3;n4->data = 4;n5->data = 5;n1->next = n2;n2->next = n3;n3->next = n4;n4->next = n5;n5->next = NULL;FindKthToTail(n1, 6);//TestSList1();//TestSList3();//TestSlist5();//TestSlist7();//TestSlist8();//TestSlist9();/*struct SListNode* n1 = (struct ListNode*)malloc(sizeof(struct SListNode));struct SListNode* n2 = (struct ListNode*)malloc(sizeof(struct SListNode));struct SListNode* n3 = (struct ListNode*)malloc(sizeof(struct SListNode));struct SListNode* n4 = (struct ListNode*)malloc(sizeof(struct SListNode));n1->data = 7;n2->data = 7;n3->data = 7;n4->data = 7;n1->next = n2;n2->next = n3;n3->next = n4;n4->next = NULL;struct SListNode* head = removeElement(n1, 7);return 0;*/}//
//
//
//
//int nums1[6] = { 1,2,3,0,0,0 };
//int nums1Size = 6;
//int m = 3;
//int nums2[3] = { 2,5,6 };
//int nums2Size = 3;
//int n = 3;int nums1[1];
int m = 0;
int nums2[1] = {1};
int n = 1;
// int p1 = m - 1, p2 = n - 1;
// int tail = m + n - 1;
// int cur;
// while (p1 > -1 || p2 > -1)
// {
// if (p1 == -1)
// {
// cur = nums2[p2--];
// }
// else if (p2 == -1)
// {
// cur = nums1[p1--];
// }
// else if (nums1[p1] > nums2[p2])
// {
// cur = nums1[p1--];
// }
// else
// {
// cur = nums2[p2--];
// }
// nums1[tail--] = cur;
// }