数据结构复习之单链表:基本操作及逆序打印、逆转、合并等

来源:互联网 发布:mysql 5.6.25安装 编辑:程序博客网 时间:2024/06/01 23:33

二叉树的定义

#include “stdafx.h”#include<malloc.h>struct ListNode;typedef int ValueType;typedef struct ListNode* ListNode;/*List是指向ListNode结构体首地址的指针,若定义List list,要使用list->value来访问结构体中的变量值,“->”运算符是取指针所指向的值。若定义struct ListNode list,则list只是个struct,访问成员变量value要使用list.value*/typedef ListNode List;  //单链表,这里使用的链表没有专门的头节点,头结节点与其他节点一样,存有一个valuestruct ListNode{    ValueType value;    struct ListNode *next;    //VS2010中可省略这一行的struct};

与上面等价、但更简洁的二叉树定义如下:

 typedef struct ListNode{    ValueType value;    struct ListNode *next;    }*ListNode, *List;

定义好数据结构之后,就可以写各种操作函数了:

 void nodeInit(ListNode node, ValueType value, ListNode next) {     node->value=value;     node->next=next; } int listLen(List list) {     if(list==NULL)         return 0;     int len=1;     ListNode p=list;     while(p->next!=NULL)     {         len++;         p=p->next;     }     return len; } //搜索简洁版:返回目标节点 ListNode find1(List list, ValueType val) {    if(list == NULL)        return NULL;    ListNode p=list;    while(p->next!=NULL && p->value != val)    {        p=p->next;    }    if(p->next == NULL)        return NULL;    return p; } //find的另一版本:若找到则返回元素的位置序号(从0开始),否则返回-1 int find2(List list,ValueType theValue) {     if(list == NULL)         return -1;     ListNode* p;     p=list;     int position=0;     int len=listLen(list);     while(p->next != NULL && p->value != theValue)     {         position++;         p = p->next;     }     if(position+1 ==len && p->value != theValue)         return -1;     return position; } //找到pos节点的前驱节点 ListNode findPrev(List list, ListNode node) {     ValueType val = node->value;     int thePos=find(list,val);     //pos节点的位置     if(list==NULL || thePos == -1 || thePos == 0)         return NULL;     ListNode p = list;     ListNode q = p->next;     while(q != NULL && q->value != val)     {         p = p->next;         q = q->next;     }     return p;  //这是在保证pos节点存在于链表中且不是头节点的情况下才返回的 }//插入简洁版:在list中node节点后面插入inserted节点void insert1(List list, ListNode node, ListNode inserted){    if(list == NULL || node == NULL || inserted == NULL)        return;    ListNode p = list;    while(p->value != node->value)    {        p = p->next;    }    if(p->value != node->value) //没找到        return;    if(p->next == NULL) //在表尾插入        p->next = inserted;    else    {        inserted->next = p->next;        p->next = inserted;    }} //在链表list中下标为position的节点后面插入值value void insert2(List *listAddr, int position, ValueType value) {     List newNode = (ListNode )malloc(sizeof(struct ListNode));     if(newNode == NULL)     {         printf("分配内存出错");         return;     }     newNode->value = value;     if(*listAddr == NULL)     {         *listAddr = newNode;         newNode->next = NULL;         return;     }     ListNode temp=*listAddr;     if(position < 0) //这时在链表最前面插入节点     {         *listAddr=newNode;         newNode->next = temp;//(ListNode )temp;     }     else if(position+1 >= listLen(*listAddr))     {         while(temp->next != NULL)         {             temp = temp->next;         }         temp->next = newNode;         newNode->next = NULL;     }     else     {         int i=0;         while(i < position)         {             temp = temp->next;             i++;         }         newNode->next = temp->next;         temp->next = newNode;     } } //删除节点 void removeNode(List *list, ValueType value) {     if(list == NULL || *list == NULL)         return;     ListNode pToBeDeleted = *list;     if((*list)->value == value)     {         *list=(*list)->next;         free(pToBeDeleted);         pToBeDeleted = NULL;     }     else     {         ListNode pre;         while(pToBeDeleted != NULL && pToBeDeleted->value != value)         {             pre=pToBeDeleted;             pToBeDeleted = pToBeDeleted->next;         }         if(pToBeDeleted == NULL)         {             if(pre->value != value)    //value不在链表中                 return;             //value位于最后一个节点中             pre->next = NULL;             free(pToBeDeleted);         }         else         {             pre->next = pToBeDeleted->next;             free(pToBeDeleted);             pToBeDeleted = NULL;         }     } } //删除链表 void removeList(List list) {     ListNode p,temp;     p=list;     while(p != NULL)     {         temp=p->next;         free(p);         p=temp;     }     list = NULL; } //从尾到首打印节点值,这个方法会改变链表结构,不好 void print(List list) {     if(list == NULL)         return;     //int len=listLen(list);     ListNode p,pre=NULL;     p=list;     while(p->next != NULL)     {         pre=p;         p = p->next;     }     printf("\n%d",p->value);     free(p);     if(pre != NULL)         pre->next = NULL;     print(list); } //上面方法的改进版 void printNodesReversing(List list) {     if(list == NULL)         return;     if(list->next != NULL)         printNodesReversing(list->next);     printf("%d\n",list->value); } //快速删除节点:可在O(1)时间内完成(对于非尾节点) //可能会对头指针操作,所以list一定要用指向指针的指针!!  void fastDelet(List *list, ListNode toBeDeleted) {     if(!list || !toBeDeleted)         return;     if(toBeDeleted->next == NULL)      //先处理特殊情况可能代码更容易写出来     {         //特殊情况:list只有一个节点          if(*list == toBeDeleted)         {             free(*list);             *list = NULL;             toBeDeleted =NULL;             return;         }         ListNode p = *list;         ListNode pre = NULL;         while(p->next != NULL)         {             pre = p;             p = p->next;         }         pre->next = NULL;         free(toBeDeleted);         toBeDeleted = NULL;     }     else     {         ListNode next = toBeDeleted->next;         toBeDeleted->value = next->value;         toBeDeleted->next = next->next;         free(next);     } } //查找链表的倒数第k(k>=1)个节点 ListNode findK(List list, int k) {     int len = listLen(list);     if(k < 1 || k > len)         return NULL;     ListNode p1 = list;     ListNode p2 = list;     int count = len;     while(p1->next != NULL)     {         count--;         if(count <= len - k)         {             p2 = p2->next;         }         p1 = p1->next;     }     return p2; } //链表逆转 //解法1:从后往前逆转,递归依次找到最后一个节点。时间O(n^2) void reverseList1(List list, int length, List newList, ListNode lastNode) {     //if(list == NULL)     //   return;     if(length <= 0)         return;     List reversed;     ListNode p = list;     ListNode pre = NULL;     for(int i = 0; i < length; i++)     {         pre = p;         p = p->next;     }     //if(pre == NULL)  //出口     //  return;     ListNode      newList = p;     newList->next = pre;     lastNode = pre;    reverseList1(list, length-1, newList,lastNode->next); } //解法2:从前往后逆转,把断开的地方缓存起来。时间O(n) List reverseList2(List list) {     if(list == NULL)         return NULL;     ListNode newHead = NULL;   //逆转之后的新表头     ListNode lastNewHead;      //上一个表头     ListNode p = list;     while(p->next != NULL)     {         lastNewHead = newHead;         newHead = p;         newHead->next = lastNewHead;         p = p->next;     }     lastNewHead = newHead;     newHead = p;     newHead->next = lastNewHead;     return newHead; } //合并两个有序链表仍保持有序,这里以升序为例 //方法1:归并排序中有序数组的合并思想,但需要定义好几个指针,比较麻烦,且容易出错 List mergeLists1(List list1, List list2) {     if(list1 == NULL)         return list2;     if(list2 == NULL)         return list1;     List newList = NULL;     ListNode p1 = list1;     ListNode p2 = list2;     ListNode lastNode = NULL;  //合并的链表尾节点     if(p1->value <= p2->value)     {         newList = p1;         lastNode = p1;         p1 = p1->next;     }     else     {         newList = p2;         lastNode = p2;         p2 = p2->next;     }     while(p1 != NULL && p2 != NULL)     {         ListNode temp = NULL;        if(p1->value <= p2->value)        {            temp = p1->next;            lastNode->next = p1;            p1 = temp;        }        else        {            temp = p2->next;            lastNode->next = p2;            p2 = temp;        }        lastNode = lastNode-> next;     }     if(p1 != NULL)         lastNode->next = p1;     if(p2 != NULL)         lastNode->next = p2;     return newList; }//方法2:利用递归,简洁明了ListNode mergeLists2(List l1, List l2){    if(l1 == NULL)        return l2;    if(l2 == NULL)        return l1;    ListNode newList;       ListNode temp;    if(l1->value <= l2->value)    {        temp = l1->next;    //要断开l1,先缓存        newList = l1;        newList->next = mergeLists2(temp, l2);    }    else    {        temp = l2->next;        newList = l2;        newList->next = mergeLists2(l1, temp);    }    return newList;}
0 0
原创粉丝点击