链表的定义:用一组任意的存储单元存储线性表的数据元素。
注意:存储单元可以是连续的,也可以是不连续的
链表的分类:
静态链表:
动态链表:
删除链表中的元素的时候,
c
// 对原链表操作
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode *tmp; // 存放临时节点,
while( head != NULL && head->val == val) // 若链表中的元素 [1,1,1,1,1] 删除的头节点
{
tmp = head;
head = head->next;
free(tmp); // 要释放的元素
}
struct ListNode * curt = head; // 删除的元素并不会改变头节点
while(curt != NULL && (tmp = curt->next))
{
if(tmp->val == val) // 若cur->next的值等于val
{
curt->next = tmp->next; // 改变链表的前驱, 将cur->next设置为cur->next->next并删除cur->next
free(tmp);
}
else
{
curt = curt->next;
}
}
return head;
}
// 构造一个虚拟头节点
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* new_head= (struct ListNode*)malloc(sizeof(struct ListNode));
new_head->next = head; // 为head构造一个虚拟节点的前驱节点
struct ListNode *cur = new_head; // 将当前节点指向head
while(cur->next != NULL)
{
if(cur->next->val == val)
{
struct ListNode *tmp = cur->next;
cur->next = cur->next->next;
free(tmp);
}
else
{
cur = cur->next;
}
}
head = new_head->next;
free(new_head);
return head;
}
考察链表的基本的操作,增删改查。
c
typedef struct Node{
int data;
struct LNode *lnext;
}LNode;
typedef struct {
int val;
LNode *next;
} MyLinkedList;
MyLinkedList* myLinkedListCreate() {
MyLinkedList *obj = (MyLinkedList *)malloc(sizeof(MyLinkedList));
LNode *head = (LNode *)malloc(sizeof(LNode));
if (!obj || !head)
{
return -1; // 分配空间失败 直接退出
}
head->lnext = NULL;
obj->next = head;
obj->val = 0;
return obj;
}
int myLinkedListGet(MyLinkedList* obj, int index) {
if (index < 0 || index >= obj->val)
{
return -1;
}
LNode *cur = obj->next;
while(index-- >= 0)
{
cur = cur->lnext;
}
return cur->data;
}
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
LNode *node = (LNode *)malloc(sizeof(LNode));
node->data = val;
node->lnext = obj->next->lnext;
obj->next->lnext = node;
obj->val ++;
}
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
LNode * cur = obj->next;
while(cur->lnext != NULL)
{
cur = cur->lnext;
}
LNode * temp = (LNode *)malloc(sizeof(LNode));
temp->data = val;
temp->lnext = NULL;;
cur->lnext = temp;
obj->val++;
}
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
if(index > obj->val)
{
return;
}
LNode * cur = obj->next;
while(index-- > 0)
{
cur = cur->lnext;
}
LNode * temp = (LNode *)malloc(sizeof(LNode)); // 为插入的节点开辟空间
temp->data = val;
temp->lnext = cur->lnext;
cur->lnext = temp;
obj->val++;
}
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
if(index < 0 || index >= obj->val)
{
return;
}
LNode *cur = obj->next;
while(index-- > 0)
{
cur = cur->lnext;
}
LNode * temp = cur->lnext;
cur->lnext = temp->lnext;
free(temp);
obj->val--;
}
void myLinkedListFree(MyLinkedList* obj) {
LNode *tmp = obj->next;
while(tmp != NULL)
{
LNode *n = tmp;
tmp = tmp->lnext;
free(n);
}
free(obj);
}
/**
* Your MyLinkedList struct will be instantiated and called as such:
* MyLinkedList* obj = myLinkedListCreate();
* int param_1 = myLinkedListGet(obj, index);
* myLinkedListAddAtHead(obj, val);
* myLinkedListAddAtTail(obj, val);
* myLinkedListAddAtIndex(obj, index, val);
* myLinkedListDeleteAtIndex(obj, index);
* myLinkedListFree(obj);
*/
链表反转:头变尾,尾变头
思路:使用双指针处理这道题
c
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode *cur = head; //保存cur的下一个结点
struct ListNode *temp; // 中间变量
struct ListNode *pre = NULL; // /pre指针指向前一个当前结点的前一个结点
while( cur != NULL)
{
temp = cur->next; //保存下一个结点的位置
cur->next = pre; //翻转操作
pre = cur; //更新结点
cur = temp;
}
return pre; //
}
// 递归解法
struct ListNode *reverse(struct ListNode *pre, struct ListNode *cur)
{
// 遍历的终止条件
if(cur == NULL)
{
return pre;
}
struct ListNode *temp = curt->next;
curt->next = pre;
return reverse(cur, temp);
}
struct ListNode *reverseList(struct ListNode *head)
{
return reverse(NULL, head);
}