文章目录
1.删除链表中的重复元素
前一个与后一个比较,相同就删除结点,并释放内存。
void DeleteEqual(PNODE &pHead){ //删除链表中的重复元素
PNODE p,q,prev;
if (p=pHead->next){
prev=p;
p=p->next;
}
while (p){
if (p->data==prev->data){
q=p;
p=p->next;
prev->next=p;
free(q);
}
else
{
prev=p;
p=p->next;
}
}
}
运行结果:
2.删除递增有序链表中大于min,小于max的元素
先找到两个前驱,释放中间结点,并且将链表重新链起来。
void DeleteSelect(PNODE &pHead,int min,int max){ //删除递增有序链表中大于min,小于max的元素
PNODE p=pHead,minPrev,maxPrev;
int flag=0;
while (p->next){
if(p->next->data>min&&!flag){
minPrev=p;
flag=1;
}
if(p->next->data>=max){
maxPrev=p;
break;
}
p=p->next;
}
PNODE temp,start;
start=minPrev->next;
while(start->data!=maxPrev->data){
temp=start;
start=start->next;
free(temp);
temp=NULL;
}
minPrev->next=maxPrev->next;
free(maxPrev);
maxPrev=NULL;
}
运行结果:
3.逆置链表
第一种策略(三指针):
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode current = head;
while(current!=null){
ListNode next = current.next;
current.next = pre;
pre = current;
current = next;
}
return pre;
}
第二种策略(递归):
总是做相同的事,就可以考虑递归的方法。
PNODE re_list(NODE *node) { //递归
if (node == NULL|| node->next == NULL) return node;
else{
NODE *head = re_list(node->next); //一直到最后一个,head为最后一个的引用,下面的语句反向
node->next->next = node;
node->next = NULL; //逆置后的最后一个指向空
return head;
}
}
void LinkListReverse2(PNODE &pHead){ //逆置链表
if (pHead == NULL || pHead->next == NULL){
return ;
}
NODE *tmp = re_list(pHead);
pHead = tmp;
}
4. 合并两个链表
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head = new ListNode(-1);
ListNode p = head;
while(l1 != null && l2 != null) {
if (l1.val < l2.val) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
if (l1 != null) {
p.next = l1;
} else if (l2 != null) {
p.next = l2;
}
return head.next;
}
4. 合并n个链表(分治法)
public ListNode mergeKLists(ListNode[] lists) {
int len = lists.length;
if (len == 0) {
return null;
}
// 将n个链表以中间为对称,两两合并
while(len>1) {
for (int i=0; i<len/2; i++) {
lists[i] = mergeTwoLists(lists[i], lists[len-1-i]);
}
len = (len+1)/2;
}
return lists[0];
}
测试代码:
#include<iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef struct Node//结点
{
int data;//数据域
struct Node *next;//指针域
}NODE, *PNODE;//NODE等价于struct Student st||PNODE等价于struct Node *next
PNODE InputStudent(void)
{
int len;
NODE stu;
PNODE pHead = (PNODE)malloc(sizeof(NODE));//定义一个头结点并且为头结点分配内存
if(NULL == pHead) //判断内存是否为空
{
printf("内存分配失败,程序终止!\n");
exit(-1);
}
PNODE pTail = pHead;//定义一个指向头结点的指针
pTail->next = NULL;//清空指针域
printf("请输入个数:");
scanf("%d",&len);
for(int i=0; i<len; i++)
{
printf("请输入第%d个:\n", i+1);
cin>>stu.data;
PNODE pNew = (PNODE)malloc(sizeof(NODE)); //为新节点分配内存
if(NULL == pNew) //判断内存是否为空
{
printf("内存分配失败,程序终止!\n");
exit(-1);
}
pNew->data = stu.data;//初始化结点的数据域
pTail->next = pNew;//将新结点挂到老结点后
pNew->next = NULL;//清空新结点的指针域
pTail = pNew;//将pTail移到新结点上
}
return pHead;
}
void OutputStudent(PNODE pHead)//输出链表
{
PNODE p = pHead->next;//定义一个指针用于遍历
printf("\n数据如下:\n");
while(NULL != p)
{
printf("%d ", p->data);
p = p->next;
}
}
void DeleteEqual(PNODE &pHead){ //删除链表中的重复元素
PNODE p,q,prev;
if (p=pHead->next){
prev=p;
p=p->next;
}
while (p){
if (p->data==prev->data){
q=p;
p=p->next;
prev->next=p;
free(q);
}
else
{
prev=p;
p=p->next;
}
}
}
void DeleteSelect(PNODE &pHead,int min,int max){ //删除递增有序链表中大于min,小于max的元素
PNODE p=pHead,minPrev,maxPrev;
int flag=0;
while (p->next){
if(p->next->data>min&&!flag){
minPrev=p;
flag=1;
}
if(p->next->data>=max){
maxPrev=p;
break;
}
p=p->next;
}
PNODE temp,start;
start=minPrev->next;
while(start->data!=maxPrev->data){
temp=start;
start=start->next;
free(temp);
temp=NULL;
}
minPrev->next=maxPrev->next;
free(maxPrev);
maxPrev=NULL;
}
void LinkListReverse(PNODE &L){ //逆置链表
PNODE pre,current,nextNode; //三个指针维持实现逆置
pre=L->next;
current=pre->next;
nextNode=current->next;
pre->next=NULL; //逆置之后为最后一个
while(nextNode->next){ //三指针依次后移实现逆置
current->next=pre;
pre=current;
current=nextNode;
nextNode=nextNode->next;
}
//循环出来后,最后的指针逆置
current->next=pre;
nextNode->next=current;
L->next=nextNode; //头结点放上就行了
}
PNODE re_list(NODE *node) { //递归
if (node == NULL|| node->next == NULL) return node;
else{
NODE *head = re_list(node->next); //一直到最后一个,head为最后一个的引用,下面的语句反向
node->next->next = node;
node->next = NULL; //逆置后的最后一个指向空
return head;
}
}
void LinkListReverse2(PNODE &pHead){ //逆置链表
if (pHead == NULL || pHead->next == NULL){
return ;
}
NODE *tmp = re_list(pHead);
pHead = tmp;
}
int main(){
PNODE L= InputStudent();
cout<<endl<<"输入的数据如下:";
OutputStudent(L);
// DeleteEqual(L);
// cout<<endl<<"删除后:";
// OutputStudent(L);
// LinkListReverse2(L->next);
// cout<<endl<<"逆置后:";
// OutputStudent(L);
DeleteSelect(L,2,10);
cout<<endl<<"删除后:";
OutputStudent(L);
return 0;
}