单链表中的常见算法问题(剑指offer5/13/15/16/17)

来源:互联网 发布:js对象和字符串区别 编辑:程序博客网 时间:2024/06/16 10:44

1.单链表的结点

struct ListNode {int m_nKey;ListNode* m_pNext;};

2.创建链表

ListNode* createList(int length) {//创建表头结点ListNode* head = new ListNode();head->m_pNext = NULL;ListNode* p = head;int value = 0; //临时存储用户键入的第i个结点值for (int i = 0; i < length; ++i) {cout << "ListNode" << i << ":\t";cin >> value;//将新创建的结点插入链表中ListNode* q = new ListNode();q->m_nKey = value;q->m_pNext = NULL;p->m_pNext = q;p = q;}return head;}

3.删除链表

void deleteList(ListNode* head) {if (NULL == head) {return;}ListNode* p = head;ListNode* q = p;while (p->m_pNext) {q = p;p = p->m_pNext;delete q;q = NULL;}delete head;head = NULL;}

4.遍历输出链表(从表头到表尾)

void showList(ListNode* head) {//如果是空链表直接退出if (NULL == head)return;ListNode* p = head->m_pNext;while (p != NULL) {cout << p->m_nKey << "\t";p = p->m_pNext;}cout << endl;}

5.链表的长度

int listLength(ListNode* head) {if (NULL == head) {return 0;}int length = 0;ListNode*p = head->m_pNext;while (NULL != p) {p = p->m_pNext;++length;}return length;}

6.链表逆置

ListNode* listReverse(ListNode* sourceHead) {if (NULL == sourceHead)return NULL;ListNode* newHead = new ListNode();newHead->m_pNext = NULL;ListNode* p = NULL; //中间结点while (sourceHead->m_pNext != NULL) {//将原来链表的第一个结点从链表中删除p = sourceHead->m_pNext;sourceHead->m_pNext = p->m_pNext;//将删除掉的结点以头插法插入到新的链表中p->m_pNext = newHead->m_pNext;newHead->m_pNext = p;}return newHead;}

7.O(1)时间删除一个指定结点

void deleteListNode(ListNode* pHeadListNode, ListNode* pToBeDeleted) {if (NULL == pHeadListNode || NULL == pToBeDeleted) {return;}//方法二:在保证链表中包含待删除结点的前提下,将待删除结点的下一个结点值//替换掉要删除结点的值,然后删除待删除结点的下一个结点//如果待删除结点是链表中的唯一结点ListNode* pHeadNext = pHeadListNode->m_pNext;if (pHeadNext == pToBeDeleted && pHeadNext ==NULL) {delete pToBeDeleted;pToBeDeleted = NULL;pHeadNext = NULL;}//如果要删除的结点不是最后一个结点,且待删除的链表的长度大于1else if (pToBeDeleted->m_pNext != NULL) {ListNode* pDeletedNext = pToBeDeleted->m_pNext;pToBeDeleted->m_nKey = pDeletedNext->m_nKey;pToBeDeleted = pDeletedNext->m_pNext;delete pDeletedNext;}//如果待删除结点是链表的末尾结点(也是最常见的操作方法)else {//方法一:找到要删除结点,用其前一个结点指向其下一个结点,从而达到删除的目的ListNode* p = pHeadListNode;ListNode* q = pHeadListNode->m_pNext;while (q != pToBeDeleted && q != NULL) {p = q;q = q->m_pNext;}if (q != NULL) {p->m_pNext = q->m_pNext;}}}

8.输出单链表中的倒数第K个结点的值

int findLastKNodeValue(ListNode* head, const unsigned int k) {if (NULL == head || k <= 0) {return -1;}//计数器unsigned int count = 0;ListNode* p = head;ListNode* q = head;//如果链表长度多于k,则q先遍历k个值while (count < k && q != NULL) {q = q->m_pNext;++count;}//如果少于k直接退出if (NULL == q) {return -1;}//如果链表的结点多于k个,两个指针一起遍历到先遍历指针为NULL时while (NULL != q) {q = q->m_pNext;p = p->m_pNext;}//当链表长度多于k时,输出倒数第k个结点的值return p->m_nKey;}

9.合并两个排序的链表

ListNode* mergeSortedLinkedList(ListNode* head1, ListNode* head2) {//有个链表为空时返回另外一个链表即可--代码的鲁棒性if (NULL == head1) {return head2;}if (NULL == head2) {return head1;}//合并后的新头 结点ListNode* head = new ListNode();head->m_pNext = NULL;ListNode* s = head;while (NULL != head1->m_pNext && NULL != head2->m_pNext) {ListNode* p = head1->m_pNext;ListNode* q = head2->m_pNext;if (p->m_nKey < q->m_nKey) {head1->m_pNext = p->m_pNext;p->m_pNext = s->m_pNext;s->m_pNext = p;s = p;} else {head2->m_pNext = q->m_pNext;q->m_pNext = s->m_pNext;s->m_pNext = q;s = q;}}while (NULL != head1->m_pNext) {ListNode* p = head1->m_pNext;head1->m_pNext = p->m_pNext;p->m_pNext = s->m_pNext;s->m_pNext = p;s = p;}while (NULL != head2->m_pNext) {ListNode* q = head2->m_pNext;head2->m_pNext = q->m_pNext;q->m_pNext = s->m_pNext;s->m_pNext = q;s = q;}return head;}

测试代码

/* * *  Created on: 2014-3-20 16:16:52 *      Author: danDingCongRong */#include<iostream>using namespace std;int main() {int listLen = 0;cout << "输入链表的长度:\t";cin >> listLen;ListNode* head = createList(listLen);cout << "原始链表:" << endl;showList(head);cout << "链表的长度为:" << listLength(head) << endl;ListNode* newHead = listReverse(head);cout << "逆置后的链表:" << endl;cout << "" << endl;showList(newHead);cout << "倒数第5个数是:" << endl;cout << findLastKNodeValue(newHead, 5) << endl;ListNode* head1 = createList(listLen);cout << "原始链表:" << endl;showList(head1);ListNode* head2 = createList(listLen);cout << "原始链表:" << endl;showList(head2);cout << "合并两个有序的链表:" << endl;ListNode* head3 = mergeSortedLinkedList(head1, head2);showList(head3);cout << "链表的长度为:" << listLength(head3) << endl;return 0;}


注:部分代码参考自剑指offer




0 0
原创粉丝点击