删除有序链表中重复出现的元素

题目描述
给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。
例如:
给出的链表为1→2→3→3→4→4→5, 返回1→2→5.
给出的链表为1→1→1→2→3, 返回2→3.

解题思路:
遍历链表的情况:
1、没有出现重复节点。
(1)就判断当前值和下一个结点的值是否相等,相等,将标志位置为真。
(2)否则,用pre指针指向当前节点, 当前结点指针指向下一个结点。
2、出现重复节点。
(1)删除重复节点,到不重复为止,将标志位置为假。

程序需要的变量:
为了好处理,先定义一个结点指向链表。
需要两个指针,一个指向需要判断的结点,一个指向前一个结点(为了删除结点后,将链表拼接)。
还需要一个标志位,判断是否出现了重复。
还需一个变量记录重复的值。

/**
 * struct ListNode {
 *    int val;
 *    struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    ListNode* deleteDuplicates(ListNode* head) {
        // write code here
        //遍历完事,用一个变量记录上一个结点的值,出现重复,删除
        struct ListNode * newhead = (struct ListNode *)malloc(sizeof(struct ListNode));

        newhead->next = head;
        ListNode * p = head;
        ListNode * pre = newhead;
        int cur = -1;
        bool flag = false;

        while(p)
        {
            //如果重复标志位假
            if(flag == false)
            {
                //判断是否重复
                if(p && p->next && p->val == p->next->val)
                {
                    cur = p->val;
                    flag = true;
                }
                else
                {
                    //不重复,下一个
                    pre = p;
                    p = p->next;
                }
            }
            else
            {
                //重复标志位真,如果值等于重复值,删除
                if(p->val == cur)
                {
                    //将p的下一个结点指针赋值给上一个结点的下一个指针
                    pre->next = p->next;
                    free(p);  //释放
                    p = pre->next;   //p 指向 下一个
                }
                else{
                    //flag 重置为false;

                    flag = false;
                }
            }
        }

        return newhead->next;



    }
};