移除链表元素 设计链表 反转链表

1.删除链表中等于给定值 val 的所有节点
#include
using namespace std;
struct ListNode{
    int val;
    ListNode* next;
    ListNode(int x)
    {
        val=x;
        next=NULL;
    }
};
ListNode* remove(ListNode* head,int val)
{
    ListNode* dummyHead=new ListNode(0);
    dummyHead->next=head;
    ListNode* cur=dummyHead;
    while(cur->next!=NULL)
    {
        if(cur->next->val==val)
        {
            ListNode* temp=cur->next;
            cur->next=cur->next->next;
            delete temp;
        }
        else
        {
            cur=cur->next;
        }
        
    }
    head=dummyHead->next;
        delete dummyHead;
        return head;
}
void printList(ListNode* head)
{
    ListNode* cur=head;
    while(cur!=NULL)
    {
        cout<val<<" ";
        cur=cur->next;
    }
    cout< }
int main()
{
    ListNode* head=new ListNode(34);
    head->next=new ListNode(54);
    head->next->next=new ListNode(89);
    head->next->next->next=new ListNode(67);
    printList(head);
    head=remove(head,54);
    printList(head);
    return 0;
}

这里使用了虚拟头节点统一了所有节点变化的规则,从虚拟头节点开始遍历,如果遇到要删除的元素,就改变指针,删除节点时创建了temp,最后要delete。

2.

在链表类中实现这些功能:

  • get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
  • addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
  • addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
  • addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
  • deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

#include
using namespace std;
struct ListNode{
    int val;
    ListNode* next;
    ListNode(int x)
    {
        val=x;
        next=NULL;
    }
};
int size=0;
ListNode* dummyHead=NULL;
InitList()
{
    size=0;
    dummyHead=new ListNode(0);
}
int get(int n)
{
    ListNode* cur=dummyHead->next;
    while(n)
    {
        cur=cur->next;
        n--;
    }
    return cur->val;
}
void Addhead(int val)
{
    ListNode* newnode=new ListNode(val);
    newnode->next=dummyHead->next;
    dummyHead->next=newnode;
    size++;
 } 
void AddTail(int val)
{
    ListNode* cur=dummyHead;
    ListNode* newnode=new ListNode(val);
    while(cur->next!=NULL)
    {
        cur=cur->next;
    }
    cur->next=newnode;
    size++;
}
void Addn(int n,int val)
{
    ListNode* cur=dummyHead;
    ListNode* newnode=new ListNode(val);
    while(n)
    {
        cur=cur->next;
        n--;
    }
    newnode->next=cur->next;
    cur->next=newnode;
    size++;
}
void deleten(int n)
{
    ListNode* cur=dummyHead;
    while(n)
    {
        cur=cur->next;
        n--;
    }
    ListNode* temp=cur->next;
    cur->next=cur->next->next;
    delete temp;
    size--;
}
void printList()
{
    ListNode* cur=dummyHead->next;
    while(cur!=NULL)
    {
        cout<val<<" ";
        cur=cur->next;
    }
    cout< }
int main()
{
    InitList();
    AddTail(3);
    AddTail(6);
    AddTail(34);
    printList();
    Addhead(4);
    printList();
    Addn(2,56);
    printList();
    deleten(3);
    printList();
    cout< }

里面使用了虚拟头节点,操作更简便。
这些是一些链表的基本操作,没有啥值得细说的,我觉得看看代码其实就能差不多理解了,挺简单的,反正熟能生巧,多敲几遍,我差不多敲了5遍,又手写了1遍,现在感觉挺熟练的。

3.反转一个单链表。

示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL

#include
using namespace std;
struct ListNode{
    int val;
    ListNode* next;
    ListNode(int x)
    {
        val=x;
        next=NULL;
    }
};
ListNode* reverse(ListNode* head)
{
    ListNode* pre=NULL;
    ListNode* cur=head;
    while(cur!=NULL)
  {
    ListNode* temp=cur->next;
    cur->next=pre;
    pre=cur;
    cur=temp;
  }
  return pre;
}
void printList(ListNode* head)
{
    ListNode* cur=head;
    while(cur!=NULL)
    {
        cout<val<<" ";
        cur=cur->next;
    }
    cout< }

int main()
{
    ListNode* head=new ListNode(2);
    head->next=new ListNode(4);
    head->next->next=new ListNode(89);
    head->next->next->next=new ListNode(65);
    printList(head);
    head=reverse(head);
    printList(head); 
    return 0;
}

该代码运用了双指针的思想,引入pre和cur指针,一开始cur指向头节点,pre指向NULL,改变cur->next,使其指向pre,但为了不出错误要提前保存cur->next到temp,而且先移动pre=cur,再移动cur=temp,否则若是先移动cur,那么pre就不能到cur了,因为cur先改变了。直到最后,cur指向NULL,pre指向头节点,最终return pre。

 

你可能感兴趣的:(算法,c++,开发语言)