您的位置:首页 > 编程语言

关于链表操作编程实现的一些总结

2015-07-28 16:25 441 查看
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

使用链表结构可以克服数组需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。链表有很多种不同的类型,单项链表、双向链表和循环链表。下面总结链表操作的代码实现。

1.单向链表

typedef struct student
{
int data;
struct student *next;
} node;

// 创建链表
node *CreateList()
{
node *head,*rear,*temp;
head = (node *)malloc(sizeof(node));
rear = head;
int flag = 1, x;

while (flag)
{
cout<<"\nPlease input the data:";
cin>>x;

if (x != 0)
{
temp = (node *)malloc(sizeof(node));
temp->data = x;
rear->next = temp;
rear = temp;
}
else
flag = 0;

}

head = head->next;
rear->next = NULL;

return head;
}

// 获取链表长度
int GetListLength(node *head)
{
int count = 0;
node *temp = head;
while (temp != NULL)
{
count++;
temp = temp->next;
}

return count;
}

// 链表内容输出
void PrintList(node *head)
{
node *temp = head;
while (temp != NULL)
{
cout<<temp->data<<" ";
temp = temp->next;
}

cout<<endl;
}

// 删除节点
node *DeleteElement(node *head, int num)
{
node *p1, *p2;
p1 = head;
if (p1 != NULL)
{
while (num != p1->data && p1->next != NULL)
{
p2 = p1;
p1 = p1->next;
}

if (num == p1->data)
{
if (p1 == head)
head = p1->next;
else
p2->next = p1->next;
free(p1);
}
else
{
cout<<"Can not find the data: "<<num<<endl;
}
}
return head;
}

// 链表逆序输出(递归函数实现)
void ReversePrintList(node *head)
{
node *temp = head;
if (temp != NULL)
{
if (temp->next != NULL)
{
ReversePrintList(temp->next);
}
cout<<temp->data<<endl;
}
}

// 链表逆置
node *ReserveList(node *head)
{
if (head == NULL || head->next == NULL)
return head;

node *t, *p1, *p2, *p;
p1 = (node *)malloc(sizeof(node));
p1->data = head->data;
p1->next = NULL;
p = p1;
t = head->next;

while (t != NULL)
{
p2 = (node *)malloc(sizeof(node));
p2->data = t->data;
p2->next = p;
p = p2;
t = t->next;
}
return p2;

}

2.双向链表

typedef struct student
{
int data;
struct student *prev;
struct student *next;
} node;

// 创建链表
node *CreateList()
{
node *head,*rear,*temp;
head = (node *)malloc(sizeof(node));
rear = head;
int flag = 1, x;

while (flag)
{
cout<<"\nPlease input the data:";
cin>>x;

if (x != 0)
{
temp = (node *)malloc(sizeof(node));
temp->data = x;
rear->next = temp;
temp->prev = rear;
rear = temp;
}
else
flag = 0;

}

head = head->next;
head->prev = NULL;
rear->next = NULL;

return head;
}
3.循环链表

typedef struct node_str
{
int data;
struct node_str *next;

}LNode, *LinkList;

// 创建循环链表(n为循环链表中元素总数)
LinkList CreateCircularList(int n)
{
LinkList head,rear,temp;
int id = 1;

head = (LinkList)malloc(sizeof(LNode));
head->data = id;
head->next = head;
rear = head;

while (--n)
{
temp = (LinkList)malloc(sizeof(LNode));
temp->data = ++id;
temp->next = rear->next;
rear->next = temp;
rear = temp;
}
return head;
}

// 输出循环链表k位置开始的m个元素(k从1开始计算)
void PrintCircularList(LinkList head, int k, int m)
{
if (head != NULL)
{
LinkList newHead = head;
k--;
while (k)
{
newHead = newHead->next;
k--;
}

for (int i=0; i<m; i++)
{
cout<<newHead->data<<endl;
newHead = newHead->next;
}
}
}

循环链表求解约瑟夫问题

// 约瑟夫环(约瑟夫问题):
// 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,
// 数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复
// 下去,直到圆桌上仅剩1人。

// 约瑟夫问题
void JOSEPHUS(int n, int m, int k)
{
// 创建循环队列
LinkList head = CreateCircularList(n);

// 将队列头移动到编号为k的位置
k--;
while (k)
{
head = head->next;
k--;
}

// 开始报数,删除节点
while (n > 1)
{
LinkList p = head, temp;
for (int i=1; i<m; i++)
{
p = head;
head = head->next;
}
temp = head;
p->next = temp->next;
head = temp->next;
free(temp);
n--;
}

// 输出最后留下人的编号
cout<<head->data<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: