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;
}
//如果要删除的结点不是最后一个结点,且待删除的链表的长度大于1
else 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